9.6 KiB
| id | ticket | title | status | created | updated | tags | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| AGD-0027 | frame-composer-public-syscall-surface | Agenda - FrameComposer Public Syscall Surface | accepted | 2026-04-17 | 2026-04-17 |
|
Contexto
DEC-0014 e os planos PLN-0017 a PLN-0021 fecharam a migração interna do pipeline de frame para FrameComposer:
FrameComposervirou o orquestrador canônico do frame;Hardwarepassou a agregá-lo ao lado deGfx;- scene, camera, cache, resolver e sprite emission migraram para ownership interno dele;
- o frame loop do runtime passou a renderizar via
FrameComposer.render_frame().
Isso resolveu a base operacional interna, mas não fechou a superfície pública equivalente para a VM. A ABI pública ainda expõe apenas o contrato legado de gfx.set_sprite(...), enquanto bind_scene(...) e set_camera(...) existem apenas como APIs internas do driver.
Na prática, hoje temos uma assimetria:
- a base canônica do frame está em
FrameComposer; - mas a ABI pública ainda não trata
FrameComposercomo serviço canônico para scene, camera e sprites.
Essa lacuna impede a migração do restante da stack e também impede um stress cartridge que atravesse de verdade o pipeline novo por syscall pública.
Problema
Precisamos definir a nova superfície pública de syscall para o pipeline canônico de FrameComposer sem reabrir a decisão já aceita sobre ownership interno do frame.
O problema concreto não é “adicionar 2 ou 3 syscalls”. Precisamos decidir:
- quais operações de
FrameComposerviram ABI pública agora; - se
gfx.set_sprite(...)continua como shim legado ou perde status canônico; - qual é o contrato mínimo de scene/camera que a VM pode observar/controlar;
- como nomear e versionar essa superfície pública sem criar um segundo modelo canônico concorrente;
- qual é a estratégia de transição para cartridge, runtime tests e stress tests;
- como propagar essa mudança para a spec canônica e, se necessário, para contratos de ABI e
ISA_CORE.
Pontos Criticos
DEC-0014já fechouFrameComposercomo base canônica interna; esta agenda não deve reabrir isso.- A ABI pública atual ainda expõe
gfx.set_sprite(...)com semântica herdada de índice/slot, mesmo que a implementação interna já use frame emission. bind_scene(scene_bank_id)eset_camera(x, y)já existem no driver, mas ainda não existem como syscalls públicas.- Se a nova ABI expuser demais logo de início, vamos congelar cedo demais detalhes que ainda não provaram valor operacional.
- Se a nova ABI expuser de menos, manteremos um modelo híbrido por tempo demais:
- canônico internamente via
FrameComposer; - legado externamente via
Gfx/set_sprite.
- canônico internamente via
- Precisamos decidir se o namespace público continua em
gfx.*por estabilidade do domínio, ou se devemos introduzir algo comoframe.*. - A transição precisa preservar compatibilidade suficiente para não quebrar cartridges e testes existentes antes da migração do restante.
- O contrato de sprite precisa deixar claro se o chamador ainda informa índice, se informa
layer, e seactivecontinua existindo na superfície pública. - A mudança não pode ficar só em código/runtime; a spec canônica precisa ser atualizada para refletir o novo serviço público.
- Se o contrato público afetar superfícies documentadas de ABI ou o material de
ISA_CORE, essa propagação precisa ser tratada como parte da mesma thread, não como follow-up solto.
Opcoes
Opcao 1 - Expor um núcleo mínimo canônico em gfx.*
Como seria: Adicionar apenas a superfície mínima para a VM controlar o pipeline novo:
gfx.bind_scene(bank_id)gfx.unbind_scene()gfx.set_camera(x, y)gfx.emit_sprite(...)
gfx.set_sprite(...) permaneceria por um período como shim legado de compatibilidade.
Vantagens:
- fecha rapidamente a lacuna operacional;
- habilita stress real do pipeline novo;
- reduz o tempo de convivência entre modelo canônico e legado;
- mantém o domínio público em
gfx, evitando churn de namespace.
Desvantagens:
- introduz ABI nova que precisará de migração coordenada;
- exige definir
emit_sprite(...)com cuidado para não herdar sem querer o modelo de slot.
Opcao 2 - Expor scene/camera agora e adiar o contrato novo de sprite
Como seria: Publicar apenas:
gfx.bind_scene(bank_id)gfx.unbind_scene()gfx.set_camera(x, y)
Sprites continuariam publicamente via gfx.set_sprite(...) até uma segunda fase.
Vantagens:
- menor mudança imediata de ABI;
- desbloqueia o stress do world path e da câmera;
- reduz o volume inicial da migração pública.
Desvantagens:
- mantém dois modelos públicos de sprite por mais tempo;
- prolonga a semântica de compatibilidade do syscall legado;
- adia exatamente uma das partes centrais da migração para
FrameComposer.
Opcao 3 - Criar um novo namespace público separado, como composer.*
Como seria: O pipeline novo ganha syscalls em um domínio separado, por exemplo:
composer.bind_scenecomposer.unbind_scenecomposer.set_cameracomposer.emit_sprite
gfx.* ficaria como superfície legacy/low-level.
Vantagens:
- deixa explícita a mudança de serviço canônico;
- evita sobrecarregar semanticamente
gfx.
Desvantagens:
- adiciona churn conceitual e de nomenclatura;
- fragmenta demais a superfície pública neste momento;
- cria um custo de transição maior sem benefício operacional evidente.
Sugestao / Recomendacao
Seguir com a Opcao 3.
Direção recomendada:
- a superfície pública canônica deve migrar para o domínio
composer.*; FrameComposervira a base canônica também na ABI pública, com namespace próprio em vez de continuar semanticamente preso agfx.*;- o núcleo mínimo público deve ser:
composer.bind_scene(bank_id) -> statuscomposer.unbind_scene()composer.set_camera(x, y)composer.emit_sprite(...) -> status
gfx.set_sprite(...)deve morrer e ser removido completamente do contrato público.
Para sprites, a recomendação provisória é:
- a nova ABI pública não deve exigir índice explícito;
composer.emit_sprite(...)deve receber o payload completo necessário para o frame:glyph_idpalette_idxylayerbank_idflip_xflip_ypriority
- a ABI pode futuramente agrupar esse payload se isso melhorar ergonomia, mas o contrato mínimo deve nascer completo;
activenão deve continuar no contrato canônico novo;- overflow continua sendo ignorado com status/telemetria adequada, sem trapar o runtime.
Para scene/camera, a recomendação provisória é:
- manter o contrato mínimo já aceito internamente;
bind_scenepor bank id;unbind_sceneexplícito;set_camera(x, y)em pixel space com top-left viewport.bind_scene(...),unbind_scene(...)eemit_sprite(...)devem usarComposerOpStatuscomo retorno operacional canônico.
Perguntas em Aberto
- Resolvido:
- o nome público canônico de sprite será
composer.emit_sprite(...); - o syscall novo de sprite nasce completo com
glyph_id,palette_id,x,y,layer,bank_id,flip_x,flip_y,priority; gfx.set_sprite(...)deve morrer e ser removido completamente;- não haverá leitura de estado nesta primeira fase;
bind_scene(...),unbind_scene(...)eemit_sprite(...)usarãoComposerOpStatus;
- o nome público canônico de sprite será
- A ABI nova precisa expor refresh explícito, ou isso deve continuar totalmente interno ao
FrameComposer? - Resolvido:
- a ABI nova não deve expor refresh explícito;
- o domínio público canônico será
composer.*, nãogfx.*.
Criterio para Encerrar
Esta agenda pode ser encerrada quando houver acordo explícito sobre:
- a lista mínima de syscalls públicas canônicas do
FrameComposer; - o nome canônico da operação pública de sprite;
- a remoção completa de
gfx.set_sprite(...)do contrato público; - o formato de retorno/status das novas operações;
- a estratégia de transição necessária para decisão, plano e migração do restante da stack.
Resolucao em Andamento
Direção atualmente acordada nesta agenda:
- o namespace público canônico será
composer.*; - o núcleo mínimo inicial será:
composer.bind_scene(bank_id) -> ComposerOpStatuscomposer.unbind_scene() -> ComposerOpStatuscomposer.set_camera(x, y)composer.emit_sprite(glyph_id, palette_id, x, y, layer, bank_id, flip_x, flip_y, priority) -> ComposerOpStatus
- não haverá introspecção pública nesta primeira fase;
- refresh/cache policy continua interno ao
FrameComposer; gfx.set_sprite(...)não terá caminho de compatibilidade e deve ser removido.
Resolucao
Esta agenda fica aceita com os seguintes pontos fechados:
- o namespace público canônico do serviço será
composer.*; - a superfície mínima inicial será:
composer.bind_scene(bank_id) -> ComposerOpStatuscomposer.unbind_scene() -> ComposerOpStatuscomposer.set_camera(x, y)composer.emit_sprite(glyph_id, palette_id, x, y, layer, bank_id, flip_x, flip_y, priority) -> ComposerOpStatus
- não haverá introspecção pública nesta primeira fase;
- não haverá refresh/cache policy público;
gfx.set_sprite(...)deve ser removido completamente, sem shim de compatibilidade;- a transição deve introduzir
composer.*e removergfx.set_sprite(...)na mesma thread de migração, com atualização coordenada de bytecode, cartridges, tests e runtime; - a mesma thread deve atualizar a spec canônica do assunto e propagar a mudança para contratos de ABI e
ISA_COREquando essas superfícies forem impactadas pelo novo serviço público.