RGBA8888 Framebuffer and Pixel Format Direction

This commit is contained in:
bQUARKz 2026-05-23 19:12:53 +01:00
parent 88ac752d9e
commit 4d5818c244
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
9 changed files with 1627 additions and 1 deletions

View File

@ -1,4 +1,4 @@
{"type":"meta","next_id":{"DSC":37,"AGD":37,"DEC":29,"PLN":67,"LSN":46,"CLSN":1}} {"type":"meta","next_id":{"DSC":38,"AGD":38,"DEC":30,"PLN":73,"LSN":46,"CLSN":1}}
{"type":"discussion","id":"DSC-0035","status":"done","ticket":"task-owned-shell-windows","title":"Agenda - Task-Owned Shell Windows","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","task","window-manager","shell","lifecycle"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0044","file":"discussion/lessons/DSC-0035-task-owned-shell-windows/LSN-0044-task-window-liveness-belongs-to-the-task.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]} {"type":"discussion","id":"DSC-0035","status":"done","ticket":"task-owned-shell-windows","title":"Agenda - Task-Owned Shell Windows","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","task","window-manager","shell","lifecycle"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0044","file":"discussion/lessons/DSC-0035-task-owned-shell-windows/LSN-0044-task-window-liveness-belongs-to-the-task.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
{"type":"discussion","id":"DSC-0034","status":"done","ticket":"system-os-domain-facades","title":"Agenda - SystemOS Domain Facades","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","services","api-surface","lifecycle","fs"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0043","file":"discussion/lessons/DSC-0034-system-os-domain-facades/LSN-0043-systemos-domain-facades.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]} {"type":"discussion","id":"DSC-0034","status":"done","ticket":"system-os-domain-facades","title":"Agenda - SystemOS Domain Facades","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","services","api-surface","lifecycle","fs"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0043","file":"discussion/lessons/DSC-0034-system-os-domain-facades/LSN-0043-systemos-domain-facades.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
{"type":"discussion","id":"DSC-0023","status":"done","ticket":"perf-full-migration-to-atomic-telemetry","title":"Agenda - [PERF] Full Migration to Atomic Telemetry","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["perf","runtime","telemetry"],"agendas":[{"id":"AGD-0021","file":"AGD-0021-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"decisions":[{"id":"DEC-0008","file":"DEC-0008-full-migration-to-atomic-telemetry.md","status":"accepted","created_at":"2026-04-10","updated_at":"2026-04-10"}],"plans":[{"id":"PLN-0007","file":"PLN-0007-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"lessons":[{"id":"LSN-0028","file":"discussion/lessons/DSC-0023-perf-full-migration-to-atomic-telemetry/LSN-0028-converging-to-single-atomic-telemetry-source.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]} {"type":"discussion","id":"DSC-0023","status":"done","ticket":"perf-full-migration-to-atomic-telemetry","title":"Agenda - [PERF] Full Migration to Atomic Telemetry","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["perf","runtime","telemetry"],"agendas":[{"id":"AGD-0021","file":"AGD-0021-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"decisions":[{"id":"DEC-0008","file":"DEC-0008-full-migration-to-atomic-telemetry.md","status":"accepted","created_at":"2026-04-10","updated_at":"2026-04-10"}],"plans":[{"id":"PLN-0007","file":"PLN-0007-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"lessons":[{"id":"LSN-0028","file":"discussion/lessons/DSC-0023-perf-full-migration-to-atomic-telemetry/LSN-0028-converging-to-single-atomic-telemetry-source.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
@ -35,3 +35,4 @@
{"type":"discussion","id":"DSC-0032","status":"done","ticket":"system-os-lifecycle-process-task-contract","title":"Agenda - SystemOS Lifecycle, Process and Task Contract","created_at":"2026-05-14","updated_at":"2026-05-15","tags":["runtime","os","lifecycle","process","task","shell","firmware"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0041","file":"discussion/lessons/DSC-0032-system-os-lifecycle-process-task-contract/LSN-0041-systemos-lifecycle-authority.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]} {"type":"discussion","id":"DSC-0032","status":"done","ticket":"system-os-lifecycle-process-task-contract","title":"Agenda - SystemOS Lifecycle, Process and Task Contract","created_at":"2026-05-14","updated_at":"2026-05-15","tags":["runtime","os","lifecycle","process","task","shell","firmware"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0041","file":"discussion/lessons/DSC-0032-system-os-lifecycle-process-task-contract/LSN-0041-systemos-lifecycle-authority.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
{"type":"discussion","id":"DSC-0033","status":"done","ticket":"system-os-service-ownership-and-module-layout","title":"Agenda - SystemOS Service Ownership and Module Layout","created_at":"2026-05-14","updated_at":"2026-05-15","tags":["runtime","os","services","module-layout","vm","window-manager","logging"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0042","file":"discussion/lessons/DSC-0033-system-os-service-ownership-and-module-layout/LSN-0042-systemos-service-ownership-boundary.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]} {"type":"discussion","id":"DSC-0033","status":"done","ticket":"system-os-service-ownership-and-module-layout","title":"Agenda - SystemOS Service Ownership and Module Layout","created_at":"2026-05-14","updated_at":"2026-05-15","tags":["runtime","os","services","module-layout","vm","window-manager","logging"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0042","file":"discussion/lessons/DSC-0033-system-os-service-ownership-and-module-layout/LSN-0042-systemos-service-ownership-boundary.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
{"type":"discussion","id":"DSC-0036","status":"done","ticket":"prometeu-hub-ui-direction","title":"Agenda - Prometeu Hub UI Direction","created_at":"2026-05-15","updated_at":"2026-05-22","tags":["hub","ui","shell","system-apps","lifecycle","design-system"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0045","file":"discussion/lessons/DSC-0036-prometeu-hub-ui-direction/LSN-0045-hub-ui-slices-should-prove-os-boundaries.md","status":"done","created_at":"2026-05-22","updated_at":"2026-05-22"}]} {"type":"discussion","id":"DSC-0036","status":"done","ticket":"prometeu-hub-ui-direction","title":"Agenda - Prometeu Hub UI Direction","created_at":"2026-05-15","updated_at":"2026-05-22","tags":["hub","ui","shell","system-apps","lifecycle","design-system"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0045","file":"discussion/lessons/DSC-0036-prometeu-hub-ui-direction/LSN-0045-hub-ui-slices-should-prove-os-boundaries.md","status":"done","created_at":"2026-05-22","updated_at":"2026-05-22"}]}
{"type":"discussion","id":"DSC-0037","status":"in_progress","ticket":"rgba8888-framebuffer-and-pixel-format-direction","title":"Agenda - RGBA8888 Framebuffer and Pixel Format Direction","created_at":"2026-05-22","updated_at":"2026-05-23","tags":["gfx","framebuffer","rgb565","rgba8888","renderer","assets","host","backend"],"agendas":[{"id":"AGD-0037","file":"AGD-0037-rgba8888-framebuffer-and-pixel-format-direction.md","status":"accepted","created_at":"2026-05-22","updated_at":"2026-05-23"}],"decisions":[{"id":"DEC-0029","file":"DEC-0029-rgba8888-runtime-pixel-format-contract.md","status":"accepted","created_at":"2026-05-23","updated_at":"2026-05-23","ref_agenda":"AGD-0037"}],"plans":[{"id":"PLN-0067","file":"PLN-0067-rgba8888-published-contracts-and-specs.md","status":"open","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0029"]},{"id":"PLN-0068","file":"PLN-0068-rgba8888-color-type-hal-and-abi-surface.md","status":"open","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0029"]},{"id":"PLN-0069","file":"PLN-0069-rgba8888-cpu-renderer-and-composition.md","status":"open","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0029"]},{"id":"PLN-0070","file":"PLN-0070-rgba8888-asset-palettes-tooling-and-fixtures.md","status":"open","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0029"]},{"id":"PLN-0071","file":"PLN-0071-rgba8888-host-presentation-path.md","status":"open","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0029"]},{"id":"PLN-0072","file":"PLN-0072-rgba8888-residue-removal-and-end-to-end-validation.md","status":"open","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0029"]}],"lessons":[]}

View File

@ -0,0 +1,763 @@
---
id: AGD-0037
ticket: rgba8888-framebuffer-and-pixel-format-direction
title: Agenda - RGBA8888 Framebuffer and Pixel Format Direction
status: accepted
created: 2026-05-22
resolved: 2026-05-23
decision: DEC-0029
tags: [gfx, framebuffer, rgb565, rgba8888, renderer, assets, host, backend]
---
## Contexto
Estamos avaliando uma possivel mudanca no Prometeu de framebuffer/cor RGB565
para RGBA8888.
O Prometeu hoje usa um modelo grafico baseado em blit destrutivo, framebuffer
proprio, tiles/sprites/layers, scene cache, paletas, fonte de hardware e
primitivas basicas de desenho. Historicamente, RGB565 foi escolhido para
reforcar a identidade de console 16-bit / fantasy handheld, reduzir memoria e
manter uma estetica simples.
Agora existe pressao legitima por RGBA8888:
- e o formato natural de muitos hosts modernos, texturas e APIs de janela;
- facilita UI mais polida, alpha real, transicoes e efeitos;
- combina melhor com a direcao do Hub estilo Homebrew Channel;
- pode reduzir conversoes no host desktop;
- abre uma ponte mais direta para backends GPU futuros.
Ao mesmo tempo, o objetivo do Prometeu continua sendo:
- hardware agnostico;
- barato/DIY quando possivel, mas sem manter RGB565 como contrato de
compatibilidade nesta mudanca;
- bom em portateis modernos;
- 480x270 a 60 Hz;
- estetica de fantasy console;
- Hub visualmente mais rico sem perder o modelo operacional;
- caminho futuro para pipeline grafico mais avancado.
Direcao atual da discussao: seguir pela Opcao B. RGB565 deve sair por completo
do contrato runtime/HAL/renderer/host/asset decode desta frente. RGBA8888 deve
ser o formato unico fisico do framebuffer e tambem a representacao normal de
cor do runtime. Esta mudanca nao deve abrir compatibilidade dupla, backend
RGB565, render thread, GPU backend ou abstracao generica de pixel format.
Esta agenda e somente analise arquitetural. Nenhum codigo deve ser alterado
como parte desta discussao.
## Estado Atual do Codigo
### Acoplamento direto a RGB565
O acoplamento central esta em `crates/console/prometeu-hal/src/color.rs`:
- `Color(pub u16)` representa explicitamente RGB565.
- `Color::rgb(r, g, b)` quantiza componentes 8-bit para 5/6/5.
- `Color::from_raw(raw: u16)` e `Color::raw() -> u16` expõem o formato fisico.
- `Color::COLOR_KEY` e `Color::TRANSPARENT` usam magenta RGB565 como chave de
transparencia.
- `unpack_to_native` e `pack_from_native` operam nos canais 5/6/5.
Isso significa que `Color` hoje nao e uma cor logica independente; ele e o
proprio pixel RGB565.
### HAL e API publica de GFX
`crates/console/prometeu-hal/src/gfx_bridge.rs` fixa RGB565 no contrato:
- `front_buffer(&self) -> &[u16]`;
- todos os draws recebem `Color`;
- fades expõem `Color`;
- o nome de syscall `GfxClear565` reforca RGB565 no contrato VM/HAL.
Impacto: qualquer migracao direta para `Vec<u32>` quebra a API do HAL, testes,
VM dispatch e host.
### Buffers do renderer
`crates/console/prometeu-drivers/src/gfx.rs` fixa o formato fisico:
- `front: Vec<u16>`;
- `back: Vec<u16>`;
- `RenderTarget.back: &mut [u16]`;
- `front_buffer() -> &[u16]`;
- `clear`, `draw_pixel`, `draw_char`, tile draw e sprite draw escrevem `u16`;
- `present()` faz swap dos dois buffers, sem copia;
- `render_scene_from_cache()` limpa o back com `Color::BLACK.raw()`;
- tiles/sprites resolvem `Color` e gravam `color.raw()`;
- fades percorrem `&mut [u16]` e fazem blend em canais RGB565.
O modelo destrutivo em si nao depende conceitualmente de RGB565, mas a
implementacao atual depende.
### Host/window layer
`crates/host/prometeu-host-desktop-winit/src/runner.rs` assume que o runtime
publica RGB565:
- le `self.hardware.gfx.front_buffer()`;
- chama `draw_rgb565_to_rgba8(src, frame)`.
`crates/host/prometeu-host-desktop-winit/src/utilities.rs` contem:
- `draw_rgb565_to_rgba8(src: &[u16], dst_rgba: &mut [u8])`;
- `rgb565_to_rgb888(px: u16)`.
Ou seja, o host `pixels` ja apresenta RGBA8, mas o runtime entrega RGB565 e o
host converte a cada redraw necessario.
### GlyphBank, paletas, sprites e scene cache
`crates/console/prometeu-hal/src/glyph_bank.rs` preserva uma separacao util:
- pixels de glyph/tile sao indices `u8`;
- payload serializado usa indices 4bpp;
- runtime expande para um `u8` por pixel;
- indice 0 e reservado para transparencia;
- a tabela de paletas e `[[Color; 16]; 64]`.
Isso acopla a resolucao final de cor a RGB565, mas nao obriga os tiles/sprites
a deixarem de ser indexados. A estrutura mais importante para preservar a
estetica fantasy console ja existe: indices + paletas limitadas.
`crates/console/prometeu-drivers/src/asset.rs` fixa o formato serializado de
paleta:
- `GLYPH_BANK_PALETTE_BYTES_V1 = 64 * 16 * size_of::<u16>()`;
- decode le cada cor como `u16::from_le_bytes`;
- escreve `Color(color_raw)`;
- testes e `pbxgen-stress` tambem assumem paletas RGB565 little-endian.
O asset pipeline atual, portanto, e v1/RGB565 para paletas, mas os indices dos
tiles/sprites podem permanecer iguais.
### Fade, blend e primitivas
`gfx.rs` implementa blend/fade em RGB565:
- `blend_rgb565(dst: u16, src: u16, mode: BlendMode) -> u16`;
- `apply_fade_to_buffer(back: &mut [u16], level, fade_color)`;
- `fill_rect_blend` mistura por pixel nos canais 5/6/5;
- `draw_text` e fonte de hardware escrevem cor opaca direta.
RGBA8888 simplificaria alguns efeitos alpha, mas tambem exigiria disciplina
para nao transformar todos os draws em blend caro por pixel.
### VM e syscall
`crates/console/prometeu-system/src/services/vm_runtime/dispatch.rs` usa:
- `get_color(value: i64) -> Color` via `Color::from_raw(value as u16)`;
- `GfxClear565`, com range `0xFFFF`.
Essa e uma fronteira importante: o PBS/VM conhece hoje o valor bruto RGB565.
Se a cor logica mudar para RGBA8888, a VM API precisa de compatibilidade ou de
uma transicao clara.
## Problema
O problema nao e apenas trocar `Vec<u16>` por `Vec<u32>`.
Existem quatro conceitos misturados hoje:
1. cor logica usada pelo runtime e HAL;
2. formato fisico do framebuffer;
3. formato serializado das paletas em `assets.pa`;
4. formato de apresentacao do host/backend.
RGB565 hoje ocupa os quatro papeis. A direcao escolhida e remove-lo desses
papeis, aceitando a quebra coordenada de HAL, asset pipeline, testes, VM, host
e renderer como o custo da limpeza arquitetural.
A pergunta arquitetural restante nao e mais se RGBA8888 deve substituir RGB565.
A resposta operacional e sim. A pergunta agora e como fazer essa substituicao
sem misturar a migracao de pixel format com render thread, GPU backend,
abstracao de backend, asset pipeline v2 amplo ou outras frentes.
## Pontos Criticos
### Identidade visual nao precisa ser formato de memoria
O Prometeu pode continuar sendo uma maquina com estetica 16-bit mesmo usando
RGBA8888 em algum ponto do pipeline. A limitacao artistica pode morar em:
- assets indexados;
- paletas limitadas;
- regras de composicao;
- resolucao 480x270;
- fontes/pixel art;
- ferramentas de autoria;
- validadores do asset pipeline.
O formato fisico do framebuffer e uma decisao de implementacao, nao
necessariamente uma promessa estetica.
### RGBA8888 como cor logica e formato fisico unico
Um tipo `Color` semanticamente RGBA8888, ou um tipo explicito
`ColorRgba8888`, deve substituir `Color(pub u16)`:
- representar alpha real;
- evitar quantizacao precoce;
- facilitar UI/HUB;
- alinhar com texturas modernas;
- eliminar a conversao obrigatoria RGB565 -> RGBA8 no host desktop.
Nesta agenda, RGBA8888 nao e apenas um backend alternativo. Ele e o formato
unico fisico do framebuffer.
### RGB565 deve sair do contrato
RGB565 continua sendo historicamente importante, mas nao deve permanecer como
compatibilidade operacional nesta mudanca. A migracao deve remover:
- `Color(pub u16)` como cor publica;
- `Vec<u16>` como front/back buffer;
- `front_buffer() -> &[u16]`;
- APIs `Gfx*565` ou qualquer outra superficie publica com formato RGB565 no
nome como APIs canonicas;
- paletas runtime armazenadas como `Color` RGB565;
- conversao host `draw_rgb565_to_rgba8` no caminho normal;
- helpers `blend_rgb565`, `pack_from_native`, `unpack_to_native` como base do
renderer.
Se algum alvo futuro precisar RGB565 por hardware, isso deve ser tratado como
uma nova discussao depois, nao como requisito desta migracao.
### O blit destrutivo pode sobreviver
RGBA8888 nao exige scene graph, GPU obrigatoria ou renderer retained. O modelo
pode continuar:
```text
frame state -> compose into back buffer -> present/publish
```
O que muda e o tipo do pixel no alvo de materializacao.
### Evitar abrir backend abstraction nesta mudanca
A VM nao deveria tocar diretamente no framebuffer. Ela deve produzir estado ou
pacotes imutaveis de frame, e o renderer deve ser dono exclusivo dos buffers.
Essa direcao continua correta no longo prazo, mas esta agenda agora restringe o
escopo. A migracao RGBA8888 deve mudar o formato atual do renderer existente,
nao introduzir uma matriz de backends. Render thread, `RenderFramePacket`
formal, SDL/GPU backend e bare-metal backend ficam fora deste corte.
O limite pragmatico: a VM/HAL nao deve expor buffer mutavel direto, mas a
implementacao deste passo pode continuar com o renderer CPU destrutivo atual,
apenas migrado para RGBA8888.
## Trade-offs Numericos
Resolucao interna atual: `480x270 = 129600` pixels.
### Memoria de framebuffer
RGB565:
- 2 bytes por pixel;
- 1 buffer: `259200` bytes = `253.125 KiB`;
- front + back: `518400` bytes = `506.25 KiB`.
RGBA8888:
- 4 bytes por pixel;
- 1 buffer: `518400` bytes = `506.25 KiB`;
- front + back: `1036800` bytes = `1012.5 KiB`.
Conclusao: RGBA8888 dobra a memoria dos framebuffers. Em desktop isso e
irrelevante; em alvo DIY/barato pode ser significativo, mas ainda e pequeno em
termos absolutos para muitos portateis modernos.
### Largura de banda por full-frame touch
Um passe que toca um buffer inteiro:
- RGB565: `253.125 KiB/frame`, cerca de `14.8 MiB/s` a 60 Hz;
- RGBA8888: `506.25 KiB/frame`, cerca de `29.7 MiB/s` a 60 Hz.
O custo real pode multiplicar isso, porque o frame atual pode fazer:
- clear;
- raster de layers;
- raster de sprites;
- scene fade fullscreen;
- hud fade fullscreen;
- conversao/apresentacao no host.
No desktop atual, a conversao host RGB565 -> RGBA8 le `253.125 KiB` e escreve
`506.25 KiB` por frame convertido, cerca de `44.5 MiB/s` a 60 Hz so nessa
etapa. Um backend RGBA8888 pode eliminar essa conversao, mas so se evitar uma
copia equivalente para o frame do host.
### CPU
Impacto esperado por operacao:
- opaque blit: RGBA8888 pode ser simples (`dst = src`), mas move o dobro de
bytes; pode ficar mais rapido em CPUs modernas se alinhar melhor a `u32`;
- masked blit: continua barato se entradas com alpha transparente pulam antes
de blendar;
- alpha blit: fica mais expressivo, mas custa multiplicacoes/interpolacoes por
canal se usado indiscriminadamente;
- fade: RGBA8888 usa canais 8-bit e pode ser mais simples conceitualmente, mas
ainda e passe fullscreen caro;
- fill_rect: pode ser rapido com fill de `u32`, desde que seja opaco;
- draw_text: continua opaco e simples, nao deve virar alpha blend por padrao;
- sprites: devem manter fast path indexado opaco/mascarado; alpha por sprite
deve ser opt-in;
- scene composition: deve continuar priorizando writes opacos e masked skips.
### Bateria
Em portateis baratos, dobrar bytes movimentados pode afetar bateria se a CPU
fizer toda composicao. Por outro lado, em portateis modernos com GPU, RGBA8888
pode economizar conversoes e usar caminhos nativos de textura/composicao.
Conclusao da agenda atual: aceitar o custo de memoria/banda do RGBA8888 como
preco de simplificacao e futuro visual. A arquitetura nao deve exigir GPU, mas
tambem nao deve manter RGB565 como fallback no escopo desta mudanca.
### Simplicidade
RGBA8888 simplifica:
- alpha real;
- integracao com host moderno;
- efeitos UI;
- raciocinio em canais 8-bit;
- possivel upload de textura.
RGBA8888 complica:
- contrato atual da VM/HAL;
- asset palette v1;
- testes que comparam `u16`;
- risco de alpha blend virar caminho padrao;
- necessidade de remover RGB565 de forma coordenada, sem camada dupla de
compatibilidade.
## Blit Destrutivo com RGBA8888
O modelo destrutivo continuaria valido:
```text
clear/fill/raster tiles/raster sprites/fades/overlay -> back buffer -> present
```
Os caminhos rapidos precisam ser explicitos:
1. Opaque blit:
- `dst = src`;
- usado para background, tiles totalmente opacos, fills, texto opaco e UI
sem alpha;
- deve ser o caminho dominante.
2. Masked blit:
- se a entrada resolvida tiver alpha transparente, pula;
- caso contrario, `dst = resolved_color`;
- deve ser o caminho dominante para sprites e tiles com recorte.
3. Alpha blit:
- `dst = src-over(dst)`;
- usado apenas quando o asset/comando declarar alpha real ou efeito;
- nao deve ser implicito para todo sprite/tile.
Para evitar que tudo vire alpha blend caro:
- manter assets indexados como opacos/mascarados por padrao;
- resolver paletas para RGBA; transparencia deve vir do canal alpha da entrada
resolvida, nao de um indice reservado;
- separar APIs/comandos `draw_opaque`, `draw_masked`, `draw_alpha`;
- manter `BlendMode` classico como efeito opt-in;
- medir alpha paths separadamente;
- nao usar RGBA8888 como desculpa para tratar cada pixel como translucido.
## Compatibilidade com Asset Pipeline
Tiles/sprites podem continuar indexados e paletizados.
Recomendacao conceitual:
- `pixel_indices: Vec<u8>` permanece;
- indices de paleta sao indices comuns; transparencia vem do canal alpha da
entrada RGBA8888 resolvida;
- limites 16 cores por paleta e 64 paletas permanecem como contrato artistico;
- paletas passam a resolver para RGBA8888;
- o payload de paleta deve deixar de ser RGB565;
- `assets.pa` e as ferramentas que geram/validam glyph banks precisam migrar
para paletas RGBA8888 no mesmo contrato desta frente.
Isso preserva o modelo artistico indexado/paletizado, mas nao preserva
compatibilidade binaria RGB565 de paleta.
Forma alvo:
```text
asset palette RGBA8888 -> decode -> [[ColorRgba8888; 16]; 64]
```
Forma transitoria aceitavel apenas durante execucao da migracao, nao como
estado final:
```text
old RGB565 test fixture -> one-time conversion -> RGBA8888 fixture
```
A decisao importante e evitar conversao por pixel a cada frame. Depois da
migracao, o renderer deve compor diretamente em RGBA8888.
## Hardware Agnostico e Backends
O jogo/PBS/VM nao deve saber detalhes de apresentacao do host, mas nesta agenda
nao criaremos multiplos backends de pixel format.
Arquitetura alvo restrita desta mudanca:
```text
VM/game tick
-> estado/comandos atuais
-> renderer CPU destrutivo compoe RGBA8888
-> host apresenta RGBA8888
```
Fora de escopo desta agenda:
- CPU RGB565 reference backend;
- suporte simultaneo RGB565/RGBA8888;
- SDL texture backend como abstracao nova;
- OpenGL ES / wgpu GPU backend;
- bare-metal framebuffer backend;
- `FrameSurface` generico com matriz de formatos.
O contrato publico deve parar de expor `&[u16]`. No alvo desta migracao, a
saida normal deve ser RGBA8888, por exemplo `&[u32]` ou bytes RGBA8 com ordem
explicitamente documentada.
Se uma abstracao generica de surface for criada, ela deve ter apenas um formato
suportado inicialmente: RGBA8888. Nao deve reintroduzir RGB565 por design.
## VM e Render Thread
A separacao VM/render thread ajuda a migracao, mas nao deve ser feita no mesmo
passo da troca de pixel format.
Modelo desejado:
- VM thread executa logica, syscalls, `frame()`, estado de sprites/cenas;
- VM nao toca diretamente no framebuffer;
- VM publica pacote imutavel de frame;
- render thread e dona exclusiva do framebuffer;
- host consome frame publicado.
Impacto na migracao para RGBA8888:
- facilita trocar backend sem afetar VM;
- reduz disputas entre VM e blit CPU no mesmo core quando houver multicore;
- exige disciplina de snapshots e ownership;
- pode aumentar latencia se a publicacao nao for bem desenhada;
- cria uma mudanca arquitetural grande demais para misturar com color format.
Portanto, render thread deve ficar fora desta frente. A migracao deve focar em
substituir RGB565 por RGBA8888 no renderer existente.
## Opcoes
### Opcao A - Manter RGB565 como framebuffer principal
**Abordagem:** preservar `Color(pub u16)`, `Vec<u16>`, asset palettes RGB565 e
host convertendo para RGBA8.
**Pros:**
- menor memoria e banda;
- baixo risco;
- preserva compatibilidade com VM/HAL/testes;
- bom para bare-metal e DIY;
- alinhado com a decisao historica de performance.
**Contras:**
- alpha real continua ruim;
- Hub moderno fica limitado ou cheio de hacks;
- host moderno paga conversao RGB565 -> RGBA8;
- formato fisico continua confundido com identidade artistica;
- backends GPU/RGBA ficam menos naturais.
**Manutenibilidade:** simples no curto prazo, mas tende a acumular excecoes
para UI e backend moderno.
### Opcao B - Migrar tudo para RGBA8888
**Abordagem:** trocar `Color` para RGBA8888, `Gfx` para `Vec<u32>`, HAL para
`&[u32]`/RGBA, host sem conversao RGB565, paletas resolvidas em RGBA. RGB565
deixa de existir como contrato runtime, formato de framebuffer, formato normal
de paleta ou backend de compatibilidade.
**Pros:**
- modelo moderno e direto;
- alpha real;
- host desktop mais natural;
- UI/HUB mais expressivo;
- caminho mais direto para GPU.
- remove a ambiguidade entre cor logica, pixel fisico e formato de host;
- reduz superficie de manutencao ao evitar suporte duplo RGB565/RGBA8888.
**Contras:**
- quebra grande de HAL/VM/testes/assets;
- dobra memoria dos framebuffers;
- pode piorar portateis baratos se tudo for CPU;
- remove RGB565 como caminho barato;
- exige migracao coordenada de fixtures, geradores de asset e syscalls.
**Manutenibilidade:** direcao aceita nesta agenda. A migracao e agressiva, mas
o resultado final e mais simples porque ha um unico formato fisico e logico.
### Opcao C - Suportar ambos via backend/pixel format desde ja
**Abordagem:** introduzir abstracao de backend/pixel format agora, com renderer
capaz de materializar RGB565 ou RGBA8888.
**Pros:**
- hardware agnostico desde o inicio;
- desktop e bare-metal podem escolher formatos naturais;
- evita uma aposta unica.
**Contras:**
- alto risco de refatoracao ampla;
- pode criar abstracao prematura;
- `Gfx` pode virar god object;
- testes dobram;
- mistura pixel format com backend abstraction antes de consolidar cor logica.
**Manutenibilidade:** boa se bem delimitada, ruim se virar uma matriz de
formatos espalhada pelo renderer.
**Status nesta agenda:** rejeitada. Suporte duplo e compatibilidade RGB565
ficam fora de escopo.
### Opcao D - RGBA8888 como cor logica, backends RGB565/RGBA8888 como destino
**Abordagem:** separar primeiro cor logica de formato fisico. Introduzir tipos
explicitos `ColorRgba8888` e `ColorRgb565`; preservar asset v1 e backend atual;
permitir que paletas/assets resolvam para cor logica ou para formato de backend
em caches preparados; migrar `Gfx`/host em etapas.
**Pros:**
- separa identidade artistica de formato de memoria;
- preserva RGB565 para targets baratos;
- prepara RGBA8888 para Hub e backends modernos;
- permite migracao incremental;
- evita mexer em render thread/GPU/asset v2 de uma vez;
- reduz confusao entre logical color e physical pixel.
**Contras:**
- adiciona tipos e conversoes;
- exige disciplina para nao converter por pixel no hot path;
- precisa planejar compatibilidade VM/HAL;
- pode manter dois mundos por um tempo.
**Manutenibilidade:** melhor equilibrio se a primeira etapa for pequena e
explícita: tipos, conversoes e fronteiras; nao backend completo imediato.
**Status nesta agenda:** rejeitada pela direcao atual. Manter RGB565 como
backend valido criaria exatamente a compatibilidade que queremos evitar.
## Sugestao / Recomendacao
Recomendacao atual: seguir pela Opcao B.
Ou seja:
- tratar RGBA8888 como formato logico e fisico unico do runtime;
- remover RGB565 por completo do contrato normal;
- preservar assets indexados/paletizados e limites artisticos;
- migrar `Gfx` para buffers RGBA8888;
- atualizar HAL, VM/syscalls, host, testes, paletas e asset tooling para
RGBA8888;
- atualizar specs, docs publicos e contratos ABI para remover RGB565,
`Gfx*565`, `u16` como contrato de cor/framebuffer e paletas RGB565;
- nao introduzir render thread, GPU backend ou abstracao multi-backend no mesmo
passo.
A identidade 16-bit/fantasy console deve ser preservada por resolucao,
paletas, assets, regras de autoria e estilo visual, nao pelo fato de todo
framebuffer fisico ser RGB565.
O caminho incremental mais seguro parece:
1. Definir o tipo de cor RGBA8888 canonico:
- `Color` pode mudar para RGBA8888, ou ser substituido por
`ColorRgba8888`;
- a representacao raw deve ser `u32` ou bytes RGBA8 documentados;
- alpha `255` deve ser o default para cores opacas.
2. Remover o contrato RGB565 do HAL/VM:
- trocar `front_buffer() -> &[u16]`;
- remover APIs de compatibilidade com sufixo de formato, como
`GfxClear565` ou qualquer superficie `Gfx*565`, e substitui-las por nomes
canonicos format-neutral, como `GfxClear`;
- atualizar validacoes de range de cor de `0xFFFF` para RGBA8888;
- atualizar testes que comparam `Color::raw()` como `u16`.
2b. Atualizar contratos publicados:
- specs canonicas;
- docs publicos;
- contratos ABI/syscall;
- qualquer documento que ainda descreva RGB565, `Gfx*565`, `u16` como cor
ou framebuffer, ou paletas RGB565.
3. Atualizar constantes e helpers:
- cores passam a ter representacao logica clara;
- `COLOR_KEY` deve virar semantica de transparencia/mascara, nao magenta
em RGB565.
4. Migrar `Gfx` para RGBA8888:
- `front/back: Vec<u32>` ou storage equivalente;
- `RenderTarget` em RGBA8888;
- `blend_rgb565` substituido por blend RGBA8888;
- fade, fill, text, tile draw e sprite draw atualizados.
5. Migrar paletas e asset tooling:
- payload de paleta deixa de ser RGB565;
- `GlyphBank.palettes` passa para RGBA8888;
- `pbxgen-stress`, fixtures e testes acompanham;
- indices de paleta deixam de carregar semantica especial de transparencia.
6. Atualizar host/window layer:
- remover `draw_rgb565_to_rgba8` do caminho normal;
- copiar/publicar RGBA8888 para `pixels` com ordem correta;
- manter overlay compativel com frame RGBA8.
7. Validar visual e performance:
- testes unitarios atualizados;
- testes de render/fade/blend;
- snapshots ou verificacoes visuais quando disponiveis;
- medicao de custo do novo frame RGBA8888.
8. Deixar explicitamente para depois:
- render thread;
- GPU backend;
- backend RGB565;
- abstracao multi-formato;
- mudancas esteticas nao necessarias para a migracao.
## Perguntas em Aberto
- [x] Queremos declarar RGBA8888 como formato logico de cor do runtime, ou
apenas como um backend fisico adicional? RGBA8888 deve ser formato logico e
fisico unico.
- [x] A VM/PBS deve continuar aceitando valores RGB565 brutos como contrato de
compatibilidade? Nao. RGB565 nao deve permanecer como compatibilidade.
- [x] `GfxClear565` deve ganhar uma syscall nova RGBA/logical color antes de
qualquer deprecacao? Nao como API com sufixo de formato. APIs criadas para
compatibilidade RGB565, como `GfxClear565` ou qualquer superficie `Gfx*565`,
devem deixar de existir; o contrato canonico deve usar nomes format-neutral,
como `GfxClear`.
- [x] `Color` deve ser renomeado para `ColorRgb565` primeiro, ou deve mudar de
semantica para RGBA com um tipo RGB565 separado? A direcao aceita e que o
contrato final exponha RGBA8888; detalhes de rename ficam para decisao/plano.
- [x] O asset `.pa` v1 deve permanecer RGB565 ate haver necessidade de `.pa` v2?
Nao como estado final desta frente. Paletas devem migrar para RGBA8888.
- [x] Paletas carregadas devem guardar RGB565, RGBA8888, ou tabelas preparadas
por backend? RGBA8888.
- [x] Alpha real deve ser permitido em paletas, em sprites separados, ou apenas
em comandos/effects/UI por enquanto? Alpha real deve ser permitido em
qualquer paleta, sprite, tile e demais superficies/elementos que precisarem
dele. Comandos dedicados para gerenciar somente alpha serao necessarios, mas
ficam fora desta wave.
- [x] Quais operacoes podem usar alpha no primeiro corte sem comprometer custo?
Todas as operacoes podem usar alpha no primeiro corte. A direcao e tudo ou
nada; otimizacao e especializacao de caminhos ficam para depois.
- [x] O backend RGBA8888 deve ser implementado primeiro no CPU renderer ou no
host desktop? No CPU renderer existente, com host atualizado para consumir
RGBA8888.
- [x] Quais testes visuais/snapshots definem equivalencia aceitavel entre
RGB565 e RGBA8888? Como RGB565 sai, equivalencia deve ser apenas de
intencao visual/composicao, nao igualdade binaria. Todos os testes devem ser
RGBA8888-first.
- [x] A decisao antiga de `AGD-0010` contra RGBA8888 no `back` continua valida
apenas para aquela fase de performance, ou deve ser substituida por uma nova
direcao mais ampla? Deve ser substituida por nova decisao especifica desta
agenda.
- [x] Qual ordem raw deve ser canonica para `u32`/bytes: RGBA, ABGR, ARGB, ou
a ordem esperada pelo `pixels` frame? RGBA.
- [x] Alpha no framebuffer final deve ser sempre `255` apos composicao, ou o
front buffer pode publicar alpha significativo? Por enquanto, o front buffer
pode publicar alpha significativo. A diretriz deve forcar o minimo possivel
e dar liberdade ao desenvolvedor.
- [x] O asset package deve mudar versao/formato explicitamente para paletas
RGBA8888 ou apenas reinterpretar metadata existente? O asset package deve
usar paletas em formato RGBA8888, sem compatibilidade com paletas RGB565,
mesmo que isso quebre assets existentes.
## Criterio para Encerrar
Esta agenda pode ser encerrada quando houver acordo sobre:
- RGBA8888 como cor logica e formato fisico unico;
- RGB565 sem papel de compatibilidade nesta frente;
- como preservar a identidade fantasy console;
- como migrar asset package, VM/HAL, host, testes e renderer;
- quais conversoes temporarias sao aceitaveis apenas durante a migracao;
- qual e a ordem incremental de substituicao;
- o que fica explicitamente fora de escopo, especialmente render thread, GPU
backend e suporte multi-formato.
Com essas respostas, a agenda deve virar uma decisao normativa antes de
qualquer edicao de spec ou codigo.
## Discussao
Entrada inicial: avaliar cuidadosamente a viabilidade de migrar o Prometeu de
RGB565 para RGBA8888, considerando estado atual do codigo, trade-offs,
compatibilidade de assets, hardware agnostico, VM/render thread, plano
incremental, riscos e uma recomendacao arquitetural.
Analise inicial, agora superada parcialmente: a migracao e viavel, mas nao
deve ser feita como troca mecanica e isolada de `u16` por `u32`. A primeira
versao da agenda considerava separar cor logica, formato fisico de framebuffer,
formato serializado de assets e formato de apresentacao do backend, preservando
RGB565 como compatibilidade. Essa preservacao nao e mais a direcao aceita.
Atualizacao em 2026-05-23: a direcao da agenda mudou para Opcao B. RGB565 deve
sair por completo, sem compatibilidade. RGBA8888 deve ser o formato unico
fisico e logico. O escopo desta frente deve ser somente migrar RGB565 para
RGBA8888 no runtime/HAL/renderer/host/assets/testes atuais, sem abrir
multi-backend, render thread ou GPU backend.
Atualizacao em 2026-05-23: as perguntas restantes foram fechadas. Alpha real
e permitido amplamente em paletas, sprites, tiles e demais operacoes; comandos
especificos para gerenciar somente alpha ficam fora desta wave. O primeiro
corte aceita alpha em todas as operacoes, deixando otimizacoes para depois.
Testes devem ser RGBA8888-first. A ordem raw canonica e RGBA. O front buffer
pode publicar alpha significativo por enquanto. O asset package deve usar
paletas RGBA8888 sem compatibilidade com assets RGB565 existentes.
## Resolucao
A agenda esta pronta para ser aceita e convertida em decisao normativa. A
direcao atual e migrar tudo para RGBA8888 como formato unico fisico e logico,
removendo RGB565 sem compatibilidade. A decisao deve cristalizar:
- RGBA8888 como contrato logico e fisico unico;
- ordem raw canonica RGBA;
- alpha significativo permitido no framebuffer publicado;
- alpha permitido em paletas, sprites, tiles e operacoes do renderer;
- comandos dedicados de alpha fora desta wave;
- testes RGBA8888-first;
- asset package com paletas RGBA8888 sem compatibilidade RGB565;
- specs, docs e contratos ABI atualizados como parte obrigatoria da propagacao;
- render thread, GPU backend, backend RGB565 e suporte multi-formato fora de
escopo.

View File

@ -0,0 +1,203 @@
---
id: DEC-0029
ticket: rgba8888-framebuffer-and-pixel-format-direction
title: RGBA8888 Runtime Pixel Format Contract
status: accepted
created: 2026-05-23
ref_agenda: AGD-0037
tags: [gfx, framebuffer, rgb565, rgba8888, renderer, assets, host, backend]
---
## Status
Accepted. Drafted from accepted agenda AGD-0037 and accepted on 2026-05-23.
Execution is split across the linked RGBA8888 migration plan family.
## Contexto
AGD-0037 evaluated whether Prometeu should keep RGB565 as the runtime color
and framebuffer contract or migrate to RGBA8888.
RGB565 is currently coupled into multiple layers:
- the public `Color(pub u16)` representation;
- HAL and VM-facing GFX APIs such as `front_buffer() -> &[u16]` and
`GfxClear565`;
- renderer front/back buffers and blending helpers;
- host presentation through RGB565-to-RGBA8 conversion;
- serialized asset palettes in `assets.pa`;
- tests and fixtures that assert RGB565 values.
The accepted agenda resolves that RGB565 should not remain as compatibility
surface in this migration. RGBA8888 becomes both the logical color contract and
the physical framebuffer format. This decision replaces the prior performance
phase direction in AGD-0010 that rejected RGBA8888 for the back buffer.
## Decisao
Prometeu SHALL migrate its normal runtime graphics contract from RGB565 to
RGBA8888.
RGBA8888 MUST be the single canonical logical color representation for the
runtime, HAL, VM-facing color values, renderer buffers, asset palette decode,
tests, and host presentation path.
RGBA8888 MUST also be the single canonical physical framebuffer format for this
wave. RGB565 MUST NOT remain as a supported runtime framebuffer backend,
compatibility mode, normal palette encoding, VM color ABI, renderer pixel
format, or host presentation contract.
The canonical raw channel order is RGBA.
The published front buffer MAY contain meaningful alpha. The runtime MUST NOT
force the final front buffer alpha channel to `255` as a blanket rule in this
wave.
Alpha is allowed broadly. Palettes, sprites, tiles, primitives, UI/effects, and
renderer operations MAY carry and apply real alpha where the operation needs
it. The first implementation wave SHALL treat alpha as available across all
operations rather than splitting the migration into alpha-capable and
alpha-forbidden paths.
Dedicated commands for managing only alpha are expected in the broader design,
but they are explicitly out of scope for this wave.
Asset packages MUST encode palettes as RGBA8888. Existing RGB565 palette assets
MUST NOT be preserved as compatible runtime input. Any old asset or fixture that
is still needed must be regenerated or converted as part of migration work, not
supported through a permanent compatibility path.
Tests MUST be RGBA8888-first. They MUST assert the new RGBA8888 contract rather
than proving binary equivalence with RGB565 output.
This decision does not introduce render thread ownership, a GPU backend, an
RGB565 backend, or a generic multi-format backend abstraction.
## Rationale
RGB565 currently plays too many roles at once: logical color, physical pixel,
serialized palette encoding, and host presentation source. Keeping it as a
compatibility layer would preserve that coupling and force the new RGBA8888
direction to coexist with an old contract that the runtime no longer wants to
guarantee.
RGBA8888 aligns better with modern host APIs, texture upload paths, alpha-based
UI, Hub visuals, and future GPU-oriented work. It also removes the mandatory
RGB565-to-RGBA8 conversion in the desktop host's normal presentation path.
The migration deliberately accepts the cost of a coordinated breaking change:
HAL, VM/syscalls, renderer buffers, asset decode, tooling, fixtures, and tests
must move together. The result is simpler than maintaining two color formats or
a premature backend matrix.
The fantasy-console identity is not tied to RGB565 memory layout. It should be
preserved by resolution, indexed assets, palette limits, art direction,
authoring constraints, and composition rules.
Allowing meaningful framebuffer alpha and broad alpha in operations keeps the
contract flexible while the renderer evolves. Performance specialization remains
important, but it should follow the correctness migration instead of blocking
the pixel-format contract.
## Invariantes / Contrato
- `Color` or its replacement MUST represent RGBA8888 semantics in the final
contract.
- Raw color values MUST use RGBA channel order.
- Runtime renderer front/back buffers MUST materialize RGBA8888 pixels.
- Public runtime/HAL/host contracts MUST stop exposing `&[u16]` as the normal
framebuffer output.
- Format-suffixed compatibility APIs such as `GfxClear565` or any other
`Gfx*565` surface MUST cease to exist in the final contract. Canonical GFX API
names MUST be format-neutral, e.g. `GfxClear`, because RGBA8888 is the only
supported runtime color contract.
- RGB565 conversion helpers may exist only as temporary migration utilities or
test-regeneration tools; they MUST NOT sit on the normal runtime hot path.
- Asset palette payloads MUST be RGBA8888.
- Indexed tile/sprite payloads MAY remain indexed/paletized; palette index
limits and 4bpp authored pixels may remain part of the artistic model.
- Palette indices are ordinary indices. Transparency MUST be represented by the
RGBA alpha channel of the resolved palette entry, not by reserving palette
index `0` as a special transparent index.
- Alpha MAY be meaningful in palettes, sprites, tiles, primitives, UI/effects,
composed framebuffer pixels, and published front-buffer pixels.
- The first migration wave MUST allow alpha across all renderer operations.
- Optimization work MAY later add faster opaque/masked/alpha paths, but that
optimization MUST NOT reintroduce RGB565 as a supported contract.
- Tests MUST use RGBA8888 expectations as source of truth.
- Render thread, GPU backend, RGB565 backend, SDL/wgpu backend abstraction, and
multi-format `FrameSurface` design are out of scope for this decision's
first execution wave.
## Impactos
### Spec
Canonical specs for GFX, assets, VM/syscalls, and host presentation need to be
updated to describe RGBA8888 as the normal color and framebuffer contract.
Published specs must be in English.
Spec updates are mandatory propagation for this decision, not follow-up cleanup.
### Runtime / HAL
The HAL color type, raw color APIs, framebuffer accessor, clear operation,
blend/fade helpers, renderer target storage, and tests must migrate away from
RGB565. Compatibility API names that encode RGB565, including any `Gfx*565`
surface, must be removed rather than carried forward as deprecated canonical
surface.
### Host
The desktop host must consume RGBA8888 frames directly in the normal path. The
existing RGB565-to-RGBA8 conversion path must be removed from normal
presentation.
### Firmware / VM / PBS
VM-facing color values and syscall validation must change from the RGB565
`0xFFFF` range to the RGBA8888 contract. PBS or syscall declarations that expose
`GfxClear565`, any other `Gfx*565` surface, or raw RGB565 color must be replaced
with format-neutral APIs such as `GfxClear`.
ABI contracts and syscall declarations are part of the required update surface.
They must not be left describing RGB565 values, `Gfx*565` names, or `u16`
framebuffer/color contracts after this migration.
### Assets / Tooling
`assets.pa`, glyph-bank palette decode, generators, fixtures, and validators
must use RGBA8888 palette entries. Compatibility with existing RGB565 palette
assets is intentionally not preserved.
### Tests
Tests must be rewritten around RGBA8888 values, RGBA channel order, broad alpha
support, meaningful front-buffer alpha, asset palette RGBA8888 encoding, and
host presentation without RGB565 conversion.
Visual/snapshot tests should assert intended RGBA8888 composition behavior, not
binary equivalence with legacy RGB565 output.
## Propagacao Necessaria
- specs: GFX peripheral, asset package/glyph-bank palette format, VM/syscall
ABI, host presentation where documented.
- plans: a dedicated execution plan must be written before spec or code edits.
- code: `prometeu-hal`, `prometeu-drivers`, `prometeu-system`,
`prometeu-host-desktop-winit`, asset tooling, fixtures.
- tests: HAL color tests, renderer tests, asset decode tests, VM/syscall tests,
host conversion/presentation tests, visual or snapshot tests where available.
- docs: discussion lessons only after execution is complete.
- canonical docs: specs, ABI contracts, and public documentation must be updated
in the same execution plan as the code/spec migration, not deferred as
optional cleanup.
## Referencias
- Agenda: AGD-0037
- Prior agenda superseded for this topic: AGD-0010
## Revision Log
- 2026-05-23: Initial decision draft from AGD-0037.

View File

@ -0,0 +1,106 @@
---
id: PLN-0067
ticket: rgba8888-framebuffer-and-pixel-format-direction
title: RGBA8888 Published Contracts and Specs
status: open
created: 2026-05-23
ref_decisions: [DEC-0029]
tags: [gfx, framebuffer, rgb565, rgba8888, renderer, assets, host, backend]
---
## Briefing
Publish the RGBA8888 contract before touching runtime code. This plan updates
the canonical specs, ABI documentation, and public docs so the repository has a
single written source of truth for the migration required by DEC-0029.
## Source Decisions
- DEC-0029 - RGBA8888 Runtime Pixel Format Contract.
## Target
Document RGBA8888 as the only supported runtime color and framebuffer contract,
remove RGB565 compatibility language from published contracts, and define
format-neutral GFX API naming rules.
## Scope
Included:
- Update `docs/specs/runtime/04-gfx-peripheral.md` to define logical color,
framebuffer output, alpha behavior, and format-neutral GFX command naming.
- Update `docs/specs/runtime/15-asset-management.md` to define RGBA8888 palette
entries in `assets.pa` and remove RGB565 palette compatibility.
- Update `docs/specs/runtime/16-host-abi-and-syscalls.md` to remove `Gfx*565`
as public ABI and define format-neutral syscall names such as `GfxClear`.
- Update `docs/specs/runtime/02a-vm-values-and-calling-convention.md` only if
it describes raw color value width/range.
- Update `docs/specs/runtime/11-portability-and-cross-platform-execution.md`
only if it describes host framebuffer format or RGB565 presentation.
- Update `docs/specs/runtime/README.md` if the index or spec summaries mention
RGB565 as current contract.
## Out of Scope
- Code changes under `crates/`.
- Asset fixture regeneration.
- Host presentation implementation.
- Lessons; they are written after execution, not before.
- New backend abstractions, render thread, GPU backend, RGB565 fallback.
## Execution Plan
1. Audit published contract text.
- Search `docs/` for `RGB565`, `rgb565`, `565`, `u16`, `GfxClear565`,
`Gfx*565`, `front_buffer`, `palette`, `assets.pa`, and `RGBA`.
- Classify each hit as historical, obsolete contract, or still-valid
implementation detail.
2. Update the GFX peripheral spec.
- State that runtime color values are RGBA8888 in RGBA channel order.
- State that front-buffer alpha may be meaningful.
- State that GFX APIs must be format-neutral and must not expose `Gfx*565`.
- State that palette indices are ordinary indices and transparency comes
from resolved RGBA alpha.
3. Update asset-management specs.
- Define palette entries as RGBA8888.
- Keep indexed tile/sprite payloads and palette limits if already specified.
- Remove compatibility promises for RGB565 palette payloads.
- Call out that existing RGB565 assets must be regenerated or converted by
tooling, not accepted as runtime compatibility input.
4. Update host and ABI specs.
- Replace RGB565 and `u16` color/framebuffer ABI language with RGBA8888.
- Replace `GfxClear565` and any `Gfx*565` surface with format-neutral names.
- Document expected syscall color range/shape for RGBA8888 values.
5. Add a short migration note to each touched spec.
- Reference DEC-0029.
- Make clear that RGB565 text is superseded for the active runtime contract.
## Acceptance Criteria
- [ ] `docs/` no longer describes RGB565 as the current runtime color,
framebuffer, palette, or host presentation contract.
- [ ] `docs/` no longer describes `Gfx*565` as public canonical ABI.
- [ ] Specs state RGBA8888 raw channel order as RGBA.
- [ ] Specs state that front-buffer alpha may be meaningful.
- [ ] Specs state that palette transparency comes from alpha, not reserved index
`0`.
- [ ] Specs state that RGB565 asset palettes are not compatible runtime input.
## Tests / Validation
- Run a repository text audit with `rg -n "RGB565|rgb565|Gfx.*565|u16|565" docs`
and verify every remaining hit is explicitly historical or unrelated.
- Run `discussion validate`.
- No Rust build is required for this docs-only plan.
## Risks
- Specs may contain old historical sections that should remain for context. If
retained, they must be marked historical and must not read as active contract.
- Some ABI names may be generated from Rust enums; this plan documents the
target but does not update generated code.

View File

@ -0,0 +1,118 @@
---
id: PLN-0068
ticket: rgba8888-framebuffer-and-pixel-format-direction
title: RGBA8888 Color Type HAL and ABI Surface
status: open
created: 2026-05-23
ref_decisions: [DEC-0029]
tags: [gfx, framebuffer, rgb565, rgba8888, renderer, assets, host, backend]
---
## Briefing
Introduce the RGBA8888 logical color contract and format-neutral HAL/ABI
surface while keeping renderer internals as stable as possible for the next
plan. This is the boundary-setting code PR after the specs are updated.
## Source Decisions
- DEC-0029 - RGBA8888 Runtime Pixel Format Contract.
## Dependencies
- PLN-0067 must be accepted or complete enough that the target spec wording is
stable.
## Target
The public runtime color type, syscall registry, ABI metadata, and HAL bridge
must stop exposing RGB565 as the canonical contract. Public names must be
format-neutral.
## Scope
Included:
- Replace `prometeu_hal::color::Color(pub u16)` semantics with RGBA8888 in
`crates/console/prometeu-hal/src/color.rs`.
- Define constructors and raw accessors for RGBA channel order.
- Preserve ergonomic named constants as RGBA8888 values.
- Replace `Syscall::GfxClear565` with format-neutral `Syscall::GfxClear`.
- Update syscall registry/domain metadata in
`crates/console/prometeu-hal/src/syscalls.rs`,
`crates/console/prometeu-hal/src/syscalls/registry.rs`, and
`crates/console/prometeu-hal/src/syscalls/domains/gfx.rs`.
- Update VM dispatch color parsing and validation in
`crates/console/prometeu-system/src/services/vm_runtime/dispatch.rs`.
- Update ABI/opcode documentation surfaces in
`crates/console/prometeu-bytecode/src/abi.rs` and
`crates/console/prometeu-bytecode/src/opcode_spec.rs` if they expose the
syscall name or raw color range.
- Change `GfxBridge::front_buffer` only if needed to compile the public API
shape; full renderer buffer migration belongs to PLN-0069.
## Out of Scope
- Migrating renderer front/back storage.
- Migrating asset palette serialization.
- Removing host RGB565 conversion.
- Performance optimization for alpha or RGBA operations.
- Adding alpha-only commands.
## Execution Plan
1. Rewrite `Color` as RGBA8888.
- Store raw color as `u32` or an equivalent transparent representation.
- `Color::rgb(r, g, b)` must create opaque alpha `255`.
- Add or update `Color::rgba(r, g, b, a)`.
- `raw()` and `from_raw()` must use RGBA channel order.
- Remove or quarantine RGB565 helpers such as 5/6/5 pack/unpack from the
canonical API.
2. Remove format-suffixed GFX syscall naming.
- Rename `GfxClear565` to `GfxClear`.
- Rename the domain metadata from `clear_565` to `clear`.
- Keep the numeric syscall id stable only if the ABI policy allows preserving
the opcode while changing the name/semantics; otherwise document the new
id in the spec before changing it.
- Search for any other `Gfx*565` public surface and rename it to
format-neutral form.
3. Update VM color ABI handling.
- Replace `0xFFFF` validation with the RGBA8888 range/shape.
- Ensure the VM passes RGBA8888 raw values into `Color`.
- Remove comments and test expectations that identify the GFX clear syscall
as RGB565.
4. Update tests at the boundary.
- HAL color tests must assert RGBA raw order.
- Syscall metadata tests must assert `GfxClear`, not `GfxClear565`.
- VM dispatch tests must use RGBA8888 values and meaningful alpha examples.
5. Run a targeted residue scan.
- `rg -n "Gfx.*565|RGB565|rgb565|0xFFFF|Color\\(.*u16|front_buffer\\(\\).*u16" crates/console`.
- Remaining hits must be either in lower layers scheduled for later plans or
marked as temporary implementation residue.
## Acceptance Criteria
- [ ] `Color` represents RGBA8888 and exposes RGBA-order raw values.
- [ ] `GfxClear565` is no longer a canonical syscall/API name; `GfxClear` is.
- [ ] No public `Gfx*565` surface remains in HAL/syscall metadata.
- [ ] VM color validation accepts RGBA8888 and does not enforce RGB565 range.
- [ ] Boundary tests are RGBA8888-first.
## Tests / Validation
- Run the HAL/syscall unit tests touched by this plan.
- Run VM dispatch tests that cover GFX clear/color values.
- Run `cargo test` for the affected crates if compile scope remains contained.
- Run `discussion validate`.
## Risks
- Renaming syscall variants may have wide compile fallout. Keep the PR focused
on boundary names and color semantics, leaving renderer internals for the next
plan.
- If opcode ids are part of a stable ABI, changing numeric ids requires a
separate explicit spec change before implementation.

View File

@ -0,0 +1,109 @@
---
id: PLN-0069
ticket: rgba8888-framebuffer-and-pixel-format-direction
title: RGBA8888 CPU Renderer and Composition
status: open
created: 2026-05-23
ref_decisions: [DEC-0029]
tags: [gfx, framebuffer, rgb565, rgba8888, renderer, assets, host, backend]
---
## Briefing
Migrate the existing CPU renderer and frame composition path from RGB565
storage to RGBA8888 storage. This plan keeps the current destructive renderer
model and does not introduce a render thread or backend abstraction.
## Source Decisions
- DEC-0029 - RGBA8888 Runtime Pixel Format Contract.
## Dependencies
- PLN-0067 for published contract wording.
- PLN-0068 for `Color`, HAL, and syscall boundary semantics.
## Target
The renderer front/back buffers, render target writes, fades, blends, text,
tiles, sprites, and frame composer tests must operate on RGBA8888 pixels.
## Scope
Included:
- `crates/console/prometeu-drivers/src/gfx.rs`.
- `crates/console/prometeu-drivers/src/frame_composer.rs`.
- `crates/console/prometeu-drivers/src/hardware.rs` where framebuffer/color
assumptions are tested or documented.
- HAL bridge implementation in drivers if it still returns `&[u16]`.
- Renderer unit tests and frame-composer tests that assert raw pixel values.
## Out of Scope
- Asset package palette serialization changes; covered by PLN-0070.
- Host presentation conversion removal; covered by PLN-0071.
- GPU backend, render thread, dirty-region optimization, span optimization, or
multi-format backend abstraction.
- Alpha-only commands.
## Execution Plan
1. Change renderer storage to RGBA8888.
- Replace `front: Vec<u16>` and `back: Vec<u16>` with RGBA8888 storage.
- Update `RenderTarget` and all buffer accessors to the new pixel type.
- Ensure `present()` keeps its swap semantics.
2. Update primitive writes.
- `clear`, `draw_pixel`, `fill_rect`, `draw_text`, hardware font drawing,
and overlay primitives must write RGBA8888 values.
- Opaque calls may write direct RGBA8888 pixels.
- Alpha values must be preserved according to the operation semantics.
3. Replace RGB565 blending/fade.
- Replace `blend_rgb565` with RGBA8888 blend logic.
- Update `apply_fade_to_buffer` to operate on RGBA channels.
- Do not force final alpha to `255`; preserve or compute alpha according to
the operation.
4. Update tile and sprite composition.
- Resolve palette entries as RGBA8888 colors.
- Do not treat palette index `0` as automatically transparent.
- Skip or blend based on resolved alpha and operation semantics.
- Allow alpha across tile, sprite, primitive, UI/effect, and fade paths.
5. Update frame composer expectations.
- Tests must assert RGBA8888 raw values.
- Any old RGB565 expected values must be regenerated from RGBA source colors,
not converted as compatibility behavior.
6. Isolate temporary compile seams.
- If asset decode still supplies RGBA8888 `Color` through old fixture bytes,
keep the fixture problem contained for PLN-0070 and do not add runtime
RGB565 compatibility to the renderer.
## Acceptance Criteria
- [ ] Renderer front/back buffers materialize RGBA8888 pixels.
- [ ] `front_buffer()` no longer exposes `&[u16]` in the driver/HAL
implementation path.
- [ ] RGB565 blend/fade helpers are removed from renderer normal paths.
- [ ] Tile/sprite transparency is based on RGBA alpha, not palette index `0`.
- [ ] Renderer and frame-composer tests assert RGBA8888 values.
- [ ] No render thread, GPU backend, RGB565 backend, or multi-format backend is
introduced.
## Tests / Validation
- Run renderer unit tests in `prometeu-drivers`.
- Run frame composer tests in `prometeu-drivers`.
- Run targeted scans for `blend_rgb565`, `Vec<u16>`, `&[u16]`, and `RGB565` in
renderer files.
- Run `discussion validate`.
## Risks
- This plan will likely touch many assertions. Keep each assertion update tied
to a known RGBA value.
- Alpha behavior can expose previously hidden assumptions in tests. Preserve the
decision rule: alpha is allowed broadly and optimization comes later.

View File

@ -0,0 +1,114 @@
---
id: PLN-0070
ticket: rgba8888-framebuffer-and-pixel-format-direction
title: RGBA8888 Asset Palettes Tooling and Fixtures
status: open
created: 2026-05-23
ref_decisions: [DEC-0029]
tags: [gfx, framebuffer, rgb565, rgba8888, renderer, assets, host, backend]
---
## Briefing
Migrate asset palette serialization, decode, generators, and fixtures to
RGBA8888. This plan intentionally breaks RGB565 palette compatibility rather
than preserving it through runtime fallback.
## Source Decisions
- DEC-0029 - RGBA8888 Runtime Pixel Format Contract.
## Dependencies
- PLN-0067 for asset spec wording.
- PLN-0068 for RGBA8888 `Color`.
- PLN-0069 may run before or alongside this plan, but renderer normal paths must
not require RGB565 palette compatibility.
## Target
`assets.pa` glyph-bank palette payloads, runtime decode, generators, and tests
must use RGBA8888 palette entries with RGBA channel order.
## Scope
Included:
- `crates/console/prometeu-hal/src/glyph_bank.rs`.
- `crates/console/prometeu-hal/src/asset.rs`.
- `crates/console/prometeu-hal/src/cartridge_loader.rs`.
- `crates/console/prometeu-drivers/src/asset.rs`.
- `crates/tools/pbxgen-stress/src/lib.rs` and related generator code.
- Runtime and system tests that compute glyph-bank payload sizes.
- Test fixtures and generated `assets.pa` payload builders in the repository.
## Out of Scope
- Supporting legacy RGB565 assets at runtime.
- Adding a general asset package v2 negotiation layer unless the existing format
requires an explicit version bump to avoid ambiguous decode.
- Changing tile/sprite index packing beyond what RGBA8888 palettes require.
- Changing palette count or colors-per-palette limits.
## Execution Plan
1. Change palette byte accounting.
- Replace palette entry size from `size_of::<u16>()` / `2` bytes to `4`
bytes.
- Update decoded-size calculations in asset decode, cartridge loader tests,
VM runtime tests, and pbxgen-stress.
2. Decode palettes as RGBA8888.
- Read each palette entry as four bytes in RGBA order.
- Construct `Color` through RGBA8888 APIs, not `Color(raw_u16)`.
- Reject payloads whose palette byte size matches old RGB565 layout when the
format can identify the mismatch.
3. Update glyph-bank semantics.
- Keep `pixel_indices: Vec<u8>` and 4bpp authored payloads where currently
specified.
- Keep palette count and colors-per-palette constants unless the spec says
otherwise.
- Remove comments that say runtime palettes are RGB565.
- Ensure palette index `0` is not treated as transparent by decode or data
model.
4. Update generators and fixtures.
- Make `pbxgen-stress` emit RGBA8888 palette bytes.
- Regenerate inline fixture builders to append four-byte RGBA palette
entries.
- Do not keep RGB565 fixture decode as runtime compatibility.
5. Update asset tests.
- Assert RGBA channel order.
- Include at least one non-opaque alpha value in a palette entry.
- Assert payload size failures for old two-byte palette layout where
practical.
## Acceptance Criteria
- [ ] Glyph-bank palette payloads are RGBA8888 and use four bytes per entry.
- [ ] Asset decode constructs RGBA8888 `Color` values in RGBA order.
- [ ] Existing RGB565 palette payloads are not accepted as compatible runtime
input.
- [ ] `pbxgen-stress` emits RGBA8888 palettes.
- [ ] Tests include meaningful alpha in palette entries.
- [ ] Palette index `0` has no special transparency semantics in asset decode.
## Tests / Validation
- Run asset decode tests in `prometeu-drivers`.
- Run cartridge loader tests in `prometeu-hal`.
- Run VM runtime asset tests in `prometeu-system`.
- Run `cargo test -p pbxgen-stress` if available.
- Run scans for `GLYPH_BANK_PALETTE.*u16`, `* 2`, `size_of::<u16>()`, and
`RGB565` in asset/glyph-bank/tooling files.
- Run `discussion validate`.
## Risks
- Payload-size constants are duplicated in tests. Update all derived size
helpers in the same PR to avoid misleading failures.
- If the existing asset package has no version marker for palette encoding, the
plan must choose an explicit metadata/version discriminator before accepting
ambiguous payloads.

View File

@ -0,0 +1,103 @@
---
id: PLN-0071
ticket: rgba8888-framebuffer-and-pixel-format-direction
title: RGBA8888 Host Presentation Path
status: open
created: 2026-05-23
ref_decisions: [DEC-0029]
tags: [gfx, framebuffer, rgb565, rgba8888, renderer, assets, host, backend]
---
## Briefing
Move the desktop host presentation path from RGB565 conversion to direct
RGBA8888 presentation. This plan removes the normal `draw_rgb565_to_rgba8`
path after the runtime publishes RGBA8888 frames.
## Source Decisions
- DEC-0029 - RGBA8888 Runtime Pixel Format Contract.
## Dependencies
- PLN-0067 for host/spec contract wording.
- PLN-0068 for public framebuffer type and ABI naming.
- PLN-0069 for renderer front-buffer RGBA8888 storage.
## Target
The host must consume RGBA8888 frames directly in the normal presentation path
and must not convert RGB565 frames on every redraw.
## Scope
Included:
- `crates/host/prometeu-host-desktop-winit/src/runner.rs`.
- `crates/host/prometeu-host-desktop-winit/src/utilities.rs`.
- Host tests or utility tests for frame copy/channel order.
- Host overlay integration where it assumes RGBA8 frame bytes.
## Out of Scope
- Changing the windowing library.
- Introducing wgpu/OpenGL/SDL backend abstractions.
- Changing host frame pacing.
- Changing render thread ownership.
- Performance optimization beyond removing RGB565 conversion from the normal
path.
## Execution Plan
1. Replace host frame conversion.
- Remove use of `draw_rgb565_to_rgba8` from `runner.rs`.
- Copy or expose RGBA8888 runtime pixels into the `pixels` frame using the
documented RGBA channel order.
- Preserve meaningful alpha unless the presentation library explicitly
requires conversion; if conversion is required, document it as host
presentation behavior, not runtime framebuffer semantics.
2. Remove RGB565 utilities from the normal path.
- Delete `draw_rgb565_to_rgba8` and `rgb565_to_rgb888` if no tests or
temporary migration tools need them.
- If temporary conversion helpers remain for fixture regeneration, move them
out of host presentation utilities and mark them non-runtime.
3. Verify overlay compatibility.
- Ensure host overlay writes still target RGBA8 bytes in the `pixels` frame.
- Ensure overlay composition does not assume the emulated framebuffer itself
is opaque.
4. Update host tests.
- Add or update tests for RGBA channel order.
- Include a source pixel with non-`255` alpha.
- Remove tests that only prove RGB565 expansion.
5. Run residue scan.
- Search host crate for `rgb565`, `RGB565`, `draw_rgb565`, and `u16`
framebuffer assumptions.
## Acceptance Criteria
- [ ] The desktop host normal redraw path consumes RGBA8888 frames.
- [ ] `draw_rgb565_to_rgba8` is not used by host presentation.
- [ ] Host channel order matches canonical RGBA.
- [ ] Host presentation does not force runtime front-buffer alpha to `255` as a
runtime contract.
- [ ] Host tests are RGBA8888-first.
## Tests / Validation
- Run `cargo test -p prometeu-host-desktop-winit`.
- Run a targeted host scan for `rgb565`, `RGB565`, and `draw_rgb565`.
- Run an interactive smoke test only if the repo already has a standard host
smoke command; otherwise record that manual visual validation remains for the
final validation plan.
- Run `discussion validate`.
## Risks
- The `pixels` frame is byte-oriented; byte order mistakes are easy. Tests must
use non-symmetric color values and non-opaque alpha.
- If runtime publishes `u32`, host code must explicitly define how the `u32`
maps to RGBA bytes instead of relying on native endian layout.

View File

@ -0,0 +1,109 @@
---
id: PLN-0072
ticket: rgba8888-framebuffer-and-pixel-format-direction
title: RGBA8888 Residue Removal and End to End Validation
status: open
created: 2026-05-23
ref_decisions: [DEC-0029]
tags: [gfx, framebuffer, rgb565, rgba8888, renderer, assets, host, backend]
---
## Briefing
Close the RGBA8888 migration by removing residual RGB565 contract text and code
paths, running end-to-end validation, and preparing the discussion thread for
post-execution lessons.
## Source Decisions
- DEC-0029 - RGBA8888 Runtime Pixel Format Contract.
## Dependencies
- PLN-0067 through PLN-0071 must be complete or merged into the execution branch.
## Target
The repository must no longer expose RGB565, `Gfx*565`, `u16` framebuffer/color
contracts, RGB565 palette payloads, or RGB565 host conversion as active runtime
contract.
## Scope
Included:
- Whole-repository residue audit.
- End-to-end build and test validation.
- Documentation consistency checks.
- Final migration notes needed for housekeeping and lessons.
- Any small missed cleanup in code, docs, tests, or fixtures that directly
violates DEC-0029.
## Out of Scope
- New alpha-only commands.
- Performance optimization after broad alpha support.
- GPU backend, render thread, RGB565 backend, multi-format backend abstraction.
- New visual design work for the Hub.
## Execution Plan
1. Run repository-wide residue scans.
- Search for `RGB565`, `rgb565`, `Gfx.*565`, `clear_565`, `u16` near color
or framebuffer APIs, `GLYPH_BANK_PALETTE.*u16`, `size_of::<u16>()` near
palette code, `draw_rgb565`, and `0xFFFF` near color validation.
- Classify every remaining hit as removed, historical-only, unrelated, or a
bug.
2. Remove active-contract residues.
- Delete or rename any remaining active `Gfx*565` surface.
- Remove RGB565 helpers from runtime and host normal paths.
- Remove comments that still describe RGB565 as current behavior.
- Remove tests that assert RGB565 output.
3. Verify docs and ABI consistency.
- Ensure `docs/specs/runtime/04-gfx-peripheral.md`,
`docs/specs/runtime/15-asset-management.md`, and
`docs/specs/runtime/16-host-abi-and-syscalls.md` agree on RGBA8888.
- Ensure public syscall declarations and docs use format-neutral names.
- Ensure any historical RGB565 mention is clearly historical and not
normative.
4. Run full test/build validation.
- Run the repo's standard build command.
- Run the relevant Rust test suites across HAL, drivers, system, VM, tools,
and host.
- Run any visual/snapshot validation available in the repository.
5. Record final evidence.
- Capture the exact commands and outcomes in the plan or final PR notes.
- List remaining historical RGB565 mentions and why they are acceptable.
- Identify lesson candidates for `discussion-housekeep` after execution.
## Acceptance Criteria
- [ ] Repository scan finds no active RGB565 runtime contract.
- [ ] No public `Gfx*565` API, syscall, metadata, or ABI declaration remains.
- [ ] No normal renderer or host path performs RGB565 conversion.
- [ ] No asset decode path accepts RGB565 palettes as compatible runtime input.
- [ ] Specs, docs, ABI contracts, code, fixtures, and tests agree on RGBA8888.
- [ ] Full validation commands pass or any failure is documented as unrelated.
- [ ] The discussion thread has enough evidence for housekeeping and lessons.
## Tests / Validation
- Run the standard repository build command.
- Run affected crate tests: `prometeu-hal`, `prometeu-drivers`,
`prometeu-system`, `prometeu-vm`, `prometeu-bytecode`,
`prometeu-host-desktop-winit`, and `pbxgen-stress` where applicable.
- Run all available visual/snapshot tests.
- Run repository-wide `rg` residue scans described above.
- Run `discussion validate`.
## Risks
- Some remaining RGB565 references may be legitimate historical notes. They
must be marked clearly enough that readers cannot mistake them for active
contract.
- End-to-end visual validation may not exist yet. If so, record the gap and add
minimal deterministic checks around RGBA channel order and alpha behavior.