prometeu-runtime/discussion/workflow/agendas/AGD-0037-rgba8888-framebuffer-and-pixel-format-direction.md

28 KiB

id ticket title status created resolved decision tags
AGD-0037 rgba8888-framebuffer-and-pixel-format-direction Agenda - RGBA8888 Framebuffer and Pixel Format Direction accepted 2026-05-22 2026-05-23 DEC-0029
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:

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:

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:

asset palette RGBA8888 -> decode -> [[ColorRgba8888; 16]; 64]

Forma transitoria aceitavel apenas durante execucao da migracao, nao como estado final:

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:

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.
  1. Atualizar constantes e helpers:

    • cores passam a ter representacao logica clara;
    • COLOR_KEY deve virar semantica de transparencia/mascara, nao magenta em RGB565.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. Deixar explicitamente para depois:

    • render thread;
    • GPU backend;
    • backend RGB565;
    • abstracao multi-formato;
    • mudancas esteticas nao necessarias para a migracao.

Perguntas em Aberto

  • 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.
  • A VM/PBS deve continuar aceitando valores RGB565 brutos como contrato de compatibilidade? Nao. RGB565 nao deve permanecer como compatibilidade.
  • 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.
  • 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.
  • O asset .pa v1 deve permanecer RGB565 ate haver necessidade de .pa v2? Nao como estado final desta frente. Paletas devem migrar para RGBA8888.
  • Paletas carregadas devem guardar RGB565, RGBA8888, ou tabelas preparadas por backend? RGBA8888.
  • 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.
  • 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.
  • O backend RGBA8888 deve ser implementado primeiro no CPU renderer ou no host desktop? No CPU renderer existente, com host atualizado para consumir RGBA8888.
  • 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.
  • 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.
  • Qual ordem raw deve ser canonica para u32/bytes: RGBA, ABGR, ARGB, ou a ordem esperada pelo pixels frame? RGBA.
  • 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.
  • 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.