Compare commits
3 Commits
38544ed3f1
...
105a6de11e
| Author | SHA1 | Date | |
|---|---|---|---|
| 105a6de11e | |||
| 96a23e5419 | |||
| 2b69be0f11 |
@ -20,6 +20,7 @@ pub mod native_helpers;
|
|||||||
pub mod native_interface;
|
pub mod native_interface;
|
||||||
pub mod pad_bridge;
|
pub mod pad_bridge;
|
||||||
pub mod primitives;
|
pub mod primitives;
|
||||||
|
pub mod render_submission;
|
||||||
pub mod sample;
|
pub mod sample;
|
||||||
pub mod scene_bank;
|
pub mod scene_bank;
|
||||||
pub mod scene_layer;
|
pub mod scene_layer;
|
||||||
@ -45,4 +46,9 @@ pub use input_signals::InputSignals;
|
|||||||
pub use native_helpers::{expect_bool, expect_int};
|
pub use native_helpers::{expect_bool, expect_int};
|
||||||
pub use native_interface::{NativeInterface, SyscallId};
|
pub use native_interface::{NativeInterface, SyscallId};
|
||||||
pub use pad_bridge::PadBridge;
|
pub use pad_bridge::PadBridge;
|
||||||
|
pub use render_submission::{
|
||||||
|
BoundScenePacket, Camera2D, ComposerFramePacket, FrameId, Game2DFramePacket, GameSpritePacket,
|
||||||
|
Gfx2dCommand, GfxUiCommand, HudCommand, HudPacket, RenderSubmission, RenderSubmissionPacket,
|
||||||
|
ShellUiFramePacket,
|
||||||
|
};
|
||||||
pub use touch_bridge::TouchBridge;
|
pub use touch_bridge::TouchBridge;
|
||||||
|
|||||||
203
crates/console/prometeu-hal/src/render_submission.rs
Normal file
203
crates/console/prometeu-hal/src/render_submission.rs
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
use crate::app_mode::AppMode;
|
||||||
|
use crate::color::Color;
|
||||||
|
use crate::primitives::Rect;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
|
pub struct FrameId(pub u64);
|
||||||
|
|
||||||
|
impl FrameId {
|
||||||
|
pub const ZERO: Self = Self(0);
|
||||||
|
|
||||||
|
pub const fn new(value: u64) -> Self {
|
||||||
|
Self(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn get(self) -> u64 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn next(self) -> Self {
|
||||||
|
Self(self.0.wrapping_add(1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct RenderSubmission {
|
||||||
|
pub frame_id: FrameId,
|
||||||
|
pub app_mode: AppMode,
|
||||||
|
pub packet: RenderSubmissionPacket,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderSubmission {
|
||||||
|
pub const fn game2d(frame_id: FrameId, packet: Game2DFramePacket) -> Self {
|
||||||
|
Self { frame_id, app_mode: AppMode::Game, packet: RenderSubmissionPacket::Game2D(packet) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn shell_ui(frame_id: FrameId, packet: ShellUiFramePacket) -> Self {
|
||||||
|
Self { frame_id, app_mode: AppMode::Shell, packet: RenderSubmissionPacket::ShellUi(packet) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn is_coherent(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
(self.app_mode, &self.packet),
|
||||||
|
(AppMode::Game, RenderSubmissionPacket::Game2D(_))
|
||||||
|
| (AppMode::Shell, RenderSubmissionPacket::ShellUi(_))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum RenderSubmissionPacket {
|
||||||
|
Game2D(Game2DFramePacket),
|
||||||
|
ShellUi(ShellUiFramePacket),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||||
|
pub struct Game2DFramePacket {
|
||||||
|
pub composer: ComposerFramePacket,
|
||||||
|
pub gfx2d: Vec<Gfx2dCommand>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Game2DFramePacket {
|
||||||
|
pub fn new(composer: ComposerFramePacket, gfx2d: Vec<Gfx2dCommand>) -> Self {
|
||||||
|
Self { composer, gfx2d }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct ShellUiFramePacket {
|
||||||
|
pub commands: Vec<GfxUiCommand>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShellUiFramePacket {
|
||||||
|
pub fn new(commands: Vec<GfxUiCommand>) -> Self {
|
||||||
|
Self { commands }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||||
|
pub struct ComposerFramePacket {
|
||||||
|
pub bound_scene: Option<BoundScenePacket>,
|
||||||
|
pub camera: Camera2D,
|
||||||
|
pub sprites: Vec<GameSpritePacket>,
|
||||||
|
pub hud: HudPacket,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub struct BoundScenePacket {
|
||||||
|
pub bank_id: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||||
|
pub struct Camera2D {
|
||||||
|
pub x: i32,
|
||||||
|
pub y: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct GameSpritePacket {
|
||||||
|
pub glyph_id: i32,
|
||||||
|
pub palette_id: i32,
|
||||||
|
pub x: i32,
|
||||||
|
pub y: i32,
|
||||||
|
pub layer: i32,
|
||||||
|
pub bank_id: i32,
|
||||||
|
pub flip_x: bool,
|
||||||
|
pub flip_y: bool,
|
||||||
|
pub priority: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||||
|
pub struct HudPacket {
|
||||||
|
pub commands: Vec<HudCommand>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum HudCommand {
|
||||||
|
Clear { color: Color },
|
||||||
|
FillRect { rect: Rect, color: Color },
|
||||||
|
DrawText { x: i32, y: i32, text: String, color: Color },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum Gfx2dCommand {
|
||||||
|
Clear { color: Color },
|
||||||
|
FillRect { rect: Rect, color: Color },
|
||||||
|
DrawLine { x0: i32, y0: i32, x1: i32, y1: i32, color: Color },
|
||||||
|
DrawCircle { x: i32, y: i32, radius: i32, color: Color },
|
||||||
|
DrawDisc { x: i32, y: i32, radius: i32, border_color: Color, fill_color: Color },
|
||||||
|
DrawSquare { rect: Rect, border_color: Color, fill_color: Color },
|
||||||
|
DrawText { x: i32, y: i32, text: String, color: Color },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum GfxUiCommand {
|
||||||
|
Clear { color: Color },
|
||||||
|
FillRect { rect: Rect, color: Color },
|
||||||
|
DrawLine { x0: i32, y0: i32, x1: i32, y1: i32, color: Color },
|
||||||
|
DrawCircle { x: i32, y: i32, radius: i32, color: Color },
|
||||||
|
DrawDisc { x: i32, y: i32, radius: i32, border_color: Color, fill_color: Color },
|
||||||
|
DrawSquare { rect: Rect, border_color: Color, fill_color: Color },
|
||||||
|
DrawText { x: i32, y: i32, text: String, color: Color },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn constructors_pin_app_mode_to_packet_kind() {
|
||||||
|
let game = RenderSubmission::game2d(FrameId::new(7), Game2DFramePacket::default());
|
||||||
|
assert_eq!(game.app_mode, AppMode::Game);
|
||||||
|
assert!(matches!(game.packet, RenderSubmissionPacket::Game2D(_)));
|
||||||
|
assert!(game.is_coherent());
|
||||||
|
|
||||||
|
let shell =
|
||||||
|
RenderSubmission::shell_ui(FrameId::new(8), ShellUiFramePacket::new(Vec::new()));
|
||||||
|
assert_eq!(shell.app_mode, AppMode::Shell);
|
||||||
|
assert!(matches!(shell.packet, RenderSubmissionPacket::ShellUi(_)));
|
||||||
|
assert!(shell.is_coherent());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn coherence_check_rejects_mismatched_envelope() {
|
||||||
|
let submission = RenderSubmission {
|
||||||
|
frame_id: FrameId::new(1),
|
||||||
|
app_mode: AppMode::Game,
|
||||||
|
packet: RenderSubmissionPacket::ShellUi(ShellUiFramePacket::new(Vec::new())),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(!submission.is_coherent());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn closed_submission_owns_command_payload() {
|
||||||
|
let mut commands = vec![Gfx2dCommand::DrawText {
|
||||||
|
x: 1,
|
||||||
|
y: 2,
|
||||||
|
text: "before".to_string(),
|
||||||
|
color: Color::WHITE,
|
||||||
|
}];
|
||||||
|
let submission = RenderSubmission::game2d(
|
||||||
|
FrameId::new(2),
|
||||||
|
Game2DFramePacket::new(Default::default(), commands.clone()),
|
||||||
|
);
|
||||||
|
|
||||||
|
commands.push(Gfx2dCommand::Clear { color: Color::BLACK });
|
||||||
|
|
||||||
|
let RenderSubmissionPacket::Game2D(packet) = submission.packet else {
|
||||||
|
panic!("expected game packet");
|
||||||
|
};
|
||||||
|
assert_eq!(packet.gfx2d.len(), 1);
|
||||||
|
assert_eq!(
|
||||||
|
packet.gfx2d[0],
|
||||||
|
Gfx2dCommand::DrawText { x: 1, y: 2, text: "before".to_string(), color: Color::WHITE }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn frame_id_advances_monotonically_with_wrapping_arithmetic() {
|
||||||
|
assert_eq!(FrameId::new(41).next(), FrameId::new(42));
|
||||||
|
assert_eq!(FrameId::new(u64::MAX).next(), FrameId::ZERO);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
{"type":"meta","next_id":{"DSC":38,"AGD":38,"DEC":30,"PLN":73,"LSN":47,"CLSN":1}}
|
{"type":"meta","next_id":{"DSC":39,"AGD":39,"DEC":31,"PLN":87,"LSN":47,"CLSN":1}}
|
||||||
|
{"type":"discussion","id":"DSC-0038","status":"in_progress","ticket":"render-frame-packet-boundary","title":"Logical Render Pipelines and Command Packets","created_at":"2026-05-25","updated_at":"2026-05-25","tags":["gfx","renderer","runtime","frame-composer","architecture","ui","pipeline"],"agendas":[{"id":"AGD-0038","file":"AGD-0038-renderframepacket-boundary-for-classic-2d-renderer.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25"}],"decisions":[{"id":"DEC-0030","file":"DEC-0030-logical-render-pipeline-command-boundary.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25","ref_agenda":"AGD-0038"}],"plans":[{"id":"PLN-0073","file":"PLN-0073-render-contract-specs.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0074","file":"PLN-0074-hal-render-submission-types.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0075","file":"PLN-0075-rendermanager-core.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0076","file":"PLN-0076-capabilities-and-abi-domain-split.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0077","file":"PLN-0077-composer-buffer-and-game2d-packet.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0078","file":"PLN-0078-classic2d-game-renderer-consumer.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0079","file":"PLN-0079-gfx2d-primitive-domain.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0080","file":"PLN-0080-shell-ui-packet-and-gfxui-domain.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0081","file":"PLN-0081-shell-hub-migration.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0082","file":"PLN-0082-frame-publication-and-present-boundary.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0083","file":"PLN-0083-fade-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0084","file":"PLN-0084-host-debug-overlay-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0085","file":"PLN-0085-pbs-stdlib-and-syscall-declarations.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0086","file":"PLN-0086-end-to-end-render-boundary-validation.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]}],"lessons":[]}
|
||||||
{"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"}]}
|
||||||
|
|||||||
@ -0,0 +1,446 @@
|
|||||||
|
---
|
||||||
|
id: AGD-0038
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: Logical Render Pipelines and Command Packets
|
||||||
|
status: accepted
|
||||||
|
created: 2026-05-25
|
||||||
|
resolved:
|
||||||
|
decision:
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Agenda - Logical Render Pipelines and Command Packets
|
||||||
|
|
||||||
|
## Contexto
|
||||||
|
|
||||||
|
Depois da migracao para RGBA8888, o proximo passo arquitetural do renderer nao deve ser GPU, 3D, multiplos backends ou troca dinamica complexa de pipeline. O objetivo imediato e separar melhor tres responsabilidades:
|
||||||
|
|
||||||
|
1. pipelines logicos produzem comandos de alto nivel;
|
||||||
|
2. uma implementacao de hardware/render surface consome esses comandos;
|
||||||
|
3. o framebuffer RGBA8888 atual continua sendo a superficie final no desktop.
|
||||||
|
|
||||||
|
A direcao desejada agora e explicitar pelo menos dois pipelines logicos:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Game 2D Pipeline
|
||||||
|
scene + sprites + HUD
|
||||||
|
-> Game2DFramePacket / Game2DCommandSet
|
||||||
|
-> hardware/render implementation
|
||||||
|
-> framebuffer RGBA8888
|
||||||
|
|
||||||
|
Prometeu UI Pipeline
|
||||||
|
shell/home/system UI/windows
|
||||||
|
-> UiFramePacket / UiCommandSet
|
||||||
|
-> hardware/render implementation
|
||||||
|
-> framebuffer RGBA8888
|
||||||
|
```
|
||||||
|
|
||||||
|
Esses pipelines podem funcionar de formas totalmente diferentes. O ponto comum nao deve ser uma API unica pobre que force tudo a parecer igual. O ponto comum deve ser a fronteira operacional: cada pipeline publica seu proprio conjunto logico de comandos para uma implementacao de hardware/superficie.
|
||||||
|
|
||||||
|
Com isso, se depois surgir um pipeline 3D, outro pipeline 2D, ou um renderer especializado para hardware barato/DIY, o trabalho fica concentrado no novo pipeline e/ou no consumidor de comandos, sem reabrir a VM inteira.
|
||||||
|
|
||||||
|
## Problema
|
||||||
|
|
||||||
|
Hoje o runtime ainda mistura producao logica de frame com desenho imediato no `Gfx`/framebuffer.
|
||||||
|
|
||||||
|
O codigo ja tem separacoes parciais:
|
||||||
|
|
||||||
|
- `FrameComposer` coordena scene binding, camera, cache/resolver e sprites do jogo.
|
||||||
|
- `Gfx` rasteriza em `back`, faz `present()` para `front`, e expoe `front_buffer()` para o host.
|
||||||
|
- `VirtualMachineRuntime` chama `hw.render_frame()` quando o frame logico termina.
|
||||||
|
- Prometeu Hub, splash/crash e varias chamadas `gfx.*` ainda desenham diretamente via `gfx_mut()`.
|
||||||
|
- O host desktop copia o `front_buffer()` RGBA8888 para `pixels`.
|
||||||
|
|
||||||
|
O limite atual ainda e "codigo logico chama renderer", nao "pipeline publica comandos para uma implementacao".
|
||||||
|
|
||||||
|
Isso cria custo futuro:
|
||||||
|
|
||||||
|
- o pipeline 2D de jogo fica preso ao formato operacional atual de `Gfx`;
|
||||||
|
- a UI do Prometeu fica misturada ao mesmo caminho imperativo de primitives;
|
||||||
|
- um futuro pipeline 3D teria que disputar o mesmo contrato em vez de definir sua propria saida logica;
|
||||||
|
- hardware barato/DIY teria que emular detalhes de `Gfx` em vez de consumir um command set adequado;
|
||||||
|
- testes ficam presos a pixels finais mesmo quando o que interessa e o pacote logico produzido.
|
||||||
|
|
||||||
|
## Pontos Criticos
|
||||||
|
|
||||||
|
### 1. Pipeline nao e backend
|
||||||
|
|
||||||
|
Pipeline deve significar "modelo logico de producao de comandos". Backend/implementacao deve significar "como esses comandos viram pixels/superficie".
|
||||||
|
|
||||||
|
Nao queremos agora:
|
||||||
|
|
||||||
|
- registry sofisticado de backends;
|
||||||
|
- troca dinamica de pipeline;
|
||||||
|
- GPU backend;
|
||||||
|
- 3D;
|
||||||
|
- refatoracao agressiva de asset pipeline;
|
||||||
|
- mudanca visual.
|
||||||
|
|
||||||
|
Queremos uma fronteira para que esses itens possam existir depois sem contaminar o passo atual.
|
||||||
|
|
||||||
|
### 2. Game 2D e Prometeu UI nao precisam compartilhar o mesmo command set
|
||||||
|
|
||||||
|
O pipeline 2D de jogos naturalmente fala de scene/cache/camera/sprites/HUD.
|
||||||
|
|
||||||
|
O pipeline de UI do Prometeu naturalmente fala de janelas, paineis, texto, retangulos, estados de foco, home/shell/system UI, talvez layout e clipping.
|
||||||
|
|
||||||
|
Forcar ambos a um `RenderCommand` generico demais no v1 pode criar uma abstracao fraca. A agenda deve decidir se o contrato comum sera:
|
||||||
|
|
||||||
|
- um enum top-level de pacotes por pipeline; ou
|
||||||
|
- uma trait de submissao ao hardware; ou
|
||||||
|
- um `FrameSubmission` que contem command sets tipados por dominio.
|
||||||
|
|
||||||
|
### 3. `FrameComposer` continua sendo bom candidato para o Game 2D Pipeline
|
||||||
|
|
||||||
|
`FrameComposer` ja e o ponto natural para produzir o pacote de jogo:
|
||||||
|
|
||||||
|
- scene binding;
|
||||||
|
- camera;
|
||||||
|
- cache/resolver;
|
||||||
|
- sprites por frame;
|
||||||
|
- HUD/primitives de jogo quando aplicavel.
|
||||||
|
|
||||||
|
O menor corte para jogo ainda parece ser transformar `FrameComposer.render_frame(&mut dyn GfxBridge)` em uma producao de `Game2DFramePacket`, consumida em seguida pelo renderer Classic2D atual.
|
||||||
|
|
||||||
|
### 4. Prometeu UI precisa sair do desenho direto, mas talvez nao no mesmo PR
|
||||||
|
|
||||||
|
Prometeu Hub e system UI hoje usam `hw.gfx_mut()` diretamente. Isso e exatamente o tipo de acoplamento que a arquitetura quer remover, mas migrar UI junto com Game 2D pode deixar a primeira mudanca grande demais.
|
||||||
|
|
||||||
|
A decisao precisa escolher entre:
|
||||||
|
|
||||||
|
- definir os dois contratos agora e implementar em fases;
|
||||||
|
- implementar primeiro Game 2D e registrar UI como segundo plan;
|
||||||
|
- ou implementar um envelope comum e dois producers minimos no mesmo plano.
|
||||||
|
|
||||||
|
### 5. HUD pertence ao pipeline 2D de jogo, nao ao Prometeu UI por padrao
|
||||||
|
|
||||||
|
Para esta agenda, "HUD" significa HUD do jogo como parte do frame de jogo: overlays do cart/gameplay, texto/debug de jogo e primitives 2D associadas ao jogo.
|
||||||
|
|
||||||
|
Prometeu UI significa UI do sistema: hub, shell, janelas, home, crash/splash se forem tratados como telas do sistema.
|
||||||
|
|
||||||
|
Essa separacao evita confundir UI de jogo com UI do console.
|
||||||
|
|
||||||
|
### 6. A implementacao inicial ainda pode ser uma so
|
||||||
|
|
||||||
|
Mesmo com dois pipelines logicos, a implementacao inicial pode continuar sendo o `Gfx`/Classic2D atual gravando em RGBA8888. O ganho arquitetural nao exige multiplos backends. Exige que a entrada da implementacao deixe de ser acesso direto ao framebuffer e passe a ser submissao de comandos logicos.
|
||||||
|
|
||||||
|
### 7. A fronteira deve preparar VM e render pipeline paralelos
|
||||||
|
|
||||||
|
Render thread nao e objetivo do v1, mas a fronteira nao deve impedir que a VM e o renderer rodem em paralelo depois.
|
||||||
|
|
||||||
|
Isso implica que a submissao de frame deve ser tratada como um snapshot fechado do trabalho de render daquele frame. Depois de publicada, a VM nao deve continuar mutando estruturas que o renderer precisa ler. A implementacao inicial pode consumir o snapshot imediatamente e no mesmo thread, mas o contrato deve evitar dependencias como `&mut Hardware`, `&mut Gfx`, ou acesso mutavel ao estado vivo da VM durante a rasterizacao.
|
||||||
|
|
||||||
|
Para o v1, isso sugere:
|
||||||
|
|
||||||
|
- `RenderSubmission` deve carregar `frame_id`, `app_mode` e dados suficientes para identificar a ordem de publicacao;
|
||||||
|
- command sets pequenos devem preferir dados owned ou buffers owned pelo produtor ate a publicacao;
|
||||||
|
- referencias pesadas, como cache/assets, devem ser read-only e ter ownership compartilhado ou lifetime claramente limitado;
|
||||||
|
- a camada de hardware/render surface deve ser a unica dona de publicacao/present;
|
||||||
|
- a VM deve produzir/submeter comandos, nao desenhar nem esperar acesso ao framebuffer;
|
||||||
|
- testes devem conseguir validar o packet/submission sem depender apenas do framebuffer final.
|
||||||
|
|
||||||
|
### 8. Deve existir um `RenderManager` acima dos pipelines
|
||||||
|
|
||||||
|
Mesmo evitando registry sofisticado de backends no v1, a arquitetura precisa de uma camada acima dos pipelines individuais. Essa camada nao deve ser "mais um pipeline"; ela deve coordenar:
|
||||||
|
|
||||||
|
- qual `AppMode` esta ativo (`Game` ou `Shell`);
|
||||||
|
- quais command buffers/submissions estao validos para esse modo;
|
||||||
|
- transicoes entre modos;
|
||||||
|
- publicacao da superficie;
|
||||||
|
- politica de latest frame;
|
||||||
|
- capacidades disponiveis por modo.
|
||||||
|
|
||||||
|
Motivacao principal: transicoes entre Shell e Game nao pertencem completamente a nenhum dos dois pipelines. Exemplo: o Shell UI pode executar uma transicao visual de saida ao abrir um jogo, mas depois que o Game 2D assume, o Shell UI ja nao existe mais para executar a transicao de entrada do jogo. Isso sugere uma base comum de render/control plane acima dos pipelines, capaz de manter transicoes e estado de superficie durante a troca de modo.
|
||||||
|
|
||||||
|
Essa camada deve se chamar `RenderManager`. O nome indica coordenacao de render, nao implementacao de desenho. A decisao precisa separar com cuidado:
|
||||||
|
|
||||||
|
- `RenderManager` como abstracao/runtime contract de coordenacao;
|
||||||
|
- host/render-surface implementation como adaptador local que sabe publicar em uma superficie real.
|
||||||
|
|
||||||
|
O `RenderManager` coordena pipelines e superficie, mas nao produz comandos de jogo/UI e nao deve conter detalhes de host desktop.
|
||||||
|
|
||||||
|
### 9. Command buffers e submissions sao conceitos diferentes
|
||||||
|
|
||||||
|
Cada dominio/pipeline acumula estado e comandos em seu proprio buffer mutavel durante o frame logico. Exemplos:
|
||||||
|
|
||||||
|
- `ComposerBuffer` para scene, camera e sprites;
|
||||||
|
- `Gfx2dBuffer` para primitivas 2D de jogo;
|
||||||
|
- `GfxUiBuffer` para primitivas de Shell UI;
|
||||||
|
- `ComposerBuffer` tambem cobre HUD do Game 2D no v1.
|
||||||
|
|
||||||
|
No fechamento do frame, o `RenderManager` transforma esses buffers na `RenderSubmission` valida para o `AppMode` atual.
|
||||||
|
|
||||||
|
Depois do fechamento, a submission e um snapshot fechado. Produtores logicos nao podem continuar mutando a submission fechada. Essa regra deve ser cravada agora porque e a base para VM e render pipeline rodarem em paralelo no futuro.
|
||||||
|
|
||||||
|
Politica de backlog: nao existe fila infinita. A regra canonica e `latest complete submission wins`.
|
||||||
|
|
||||||
|
## Opcoes
|
||||||
|
|
||||||
|
### Opcao A - Dois command sets tipados, uma implementacao Classic2D inicial
|
||||||
|
|
||||||
|
**Abordagem:**
|
||||||
|
|
||||||
|
- Criar `Game2DFramePacket` para scene/sprites/HUD.
|
||||||
|
- Criar `UiFramePacket` para Prometeu UI/system UI.
|
||||||
|
- Criar um envelope simples, por exemplo `RenderSubmission`, que identifica qual pacote esta sendo submetido.
|
||||||
|
- Fazer a implementacao Classic2D atual consumir os pacotes e continuar escrevendo no framebuffer RGBA8888.
|
||||||
|
- Implementar em fases: primeiro Game 2D, depois Prometeu UI, ou ambos com producers minimos se o plano ficar pequeno o suficiente.
|
||||||
|
|
||||||
|
**Pro:**
|
||||||
|
|
||||||
|
- preserva modelos logicos diferentes para jogo e UI;
|
||||||
|
- evita uma command list generica demais;
|
||||||
|
- prepara 3D ou outros pipelines sem forcar eles a parecerem com 2D;
|
||||||
|
- deixa claro que pipeline e backend sao coisas diferentes.
|
||||||
|
|
||||||
|
**Con:**
|
||||||
|
|
||||||
|
- cria mais tipos no inicio;
|
||||||
|
- precisa definir como o hardware recebe pacotes heterogeneos;
|
||||||
|
- se so Game 2D for migrado no primeiro plan, UI continua acoplada por um tempo.
|
||||||
|
|
||||||
|
**Maintainability:**
|
||||||
|
|
||||||
|
Alta. Esta opcao combina com a direcao de longo prazo sem exigir varios backends agora.
|
||||||
|
|
||||||
|
### Opcao B - Um `RenderCommand` universal para tudo
|
||||||
|
|
||||||
|
**Abordagem:**
|
||||||
|
|
||||||
|
- Criar uma display list unica com comandos como `Clear`, `DrawSprite`, `DrawText`, `FillRect`, `SceneCache`, `Window`, `Transition`.
|
||||||
|
- Fazer Game 2D e Prometeu UI emitirem a mesma lista.
|
||||||
|
|
||||||
|
**Pro:**
|
||||||
|
|
||||||
|
- facil de passar por uma unica fila;
|
||||||
|
- simples para logging/replay inicial;
|
||||||
|
- reduz o numero de tipos.
|
||||||
|
|
||||||
|
**Con:**
|
||||||
|
|
||||||
|
- tende a virar um denominador comum fraco;
|
||||||
|
- mistura semantica de jogo, UI de sistema e futuros pipelines;
|
||||||
|
- pode forcar o pipeline 3D futuro a um contrato 2D inadequado;
|
||||||
|
- aumenta chance de reabrir a arquitetura quando outro pipeline surgir.
|
||||||
|
|
||||||
|
**Maintainability:**
|
||||||
|
|
||||||
|
Media a baixa como arquitetura principal. Pode ser util internamente dentro de um pipeline, mas nao como contrato unico do runtime.
|
||||||
|
|
||||||
|
### Opcao C - Trait comum de pipeline, sem pacote explicito
|
||||||
|
|
||||||
|
**Abordagem:**
|
||||||
|
|
||||||
|
- Definir algo como `RenderPipeline` com metodo `render(&mut HardwareSurface)`.
|
||||||
|
- Game 2D e UI implementam a trait, mas continuam desenhando por callbacks imediatos.
|
||||||
|
|
||||||
|
**Pro:**
|
||||||
|
|
||||||
|
- pequena mudanca inicial;
|
||||||
|
- organiza nomes e ownership;
|
||||||
|
- reduz um pouco o acoplamento por modulo.
|
||||||
|
|
||||||
|
**Con:**
|
||||||
|
|
||||||
|
- nao cria pacote logico observavel;
|
||||||
|
- continua misturando producao e execucao;
|
||||||
|
- nao ajuda tanto render thread, replay, testes de comandos ou hardware alternativo.
|
||||||
|
|
||||||
|
**Maintainability:**
|
||||||
|
|
||||||
|
Insuficiente se virar a decisao final. Pode ser uma API auxiliar, mas nao substitui command packets.
|
||||||
|
|
||||||
|
### Opcao D - Definir todos os pipelines e backend abstraction agora
|
||||||
|
|
||||||
|
**Abordagem:**
|
||||||
|
|
||||||
|
- Criar pipeline registry, backend interfaces, CPU/GPU abstractions, surfaces, scheduling, command queues e talvez render thread.
|
||||||
|
|
||||||
|
**Pro:**
|
||||||
|
|
||||||
|
- parece completo no papel;
|
||||||
|
- antecipa muitos cenarios futuros.
|
||||||
|
|
||||||
|
**Con:**
|
||||||
|
|
||||||
|
- grande demais para o objetivo atual;
|
||||||
|
- alto risco de abstrair sem uso real;
|
||||||
|
- pode atrasar a estabilizacao do 2D atual;
|
||||||
|
- tende a introduzir nomes e contratos que depois precisarao ser quebrados.
|
||||||
|
|
||||||
|
**Maintainability:**
|
||||||
|
|
||||||
|
Baixa para o momento atual. Melhor deixar essa camada emergir depois de pelo menos dois pipelines reais funcionando.
|
||||||
|
|
||||||
|
## Sugestao / Recomendacao
|
||||||
|
|
||||||
|
A recomendacao atual e a Opcao A: definir dois pipelines logicos com command sets proprios e uma implementacao Classic2D inicial.
|
||||||
|
|
||||||
|
Modelo recomendado:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Game2DPipeline
|
||||||
|
produces Game2DFramePacket
|
||||||
|
owns/uses FrameComposer concepts:
|
||||||
|
scene/cache/camera
|
||||||
|
sprites
|
||||||
|
game HUD
|
||||||
|
HUD/primitives
|
||||||
|
|
||||||
|
PrometeuUiPipeline
|
||||||
|
produces UiFramePacket
|
||||||
|
owns/uses system UI concepts:
|
||||||
|
home/hub
|
||||||
|
shell windows
|
||||||
|
panels/rects/text
|
||||||
|
focus/input visual state
|
||||||
|
|
||||||
|
RenderHardware / RenderSurface implementation
|
||||||
|
consumes typed submissions:
|
||||||
|
Game2D(Game2DFramePacket)
|
||||||
|
PrometeuUi(UiFramePacket)
|
||||||
|
future: Game3D(...), Custom2D(...), etc.
|
||||||
|
writes to current RGBA8888 framebuffer for now
|
||||||
|
|
||||||
|
RenderManager
|
||||||
|
owns current AppMode render routing
|
||||||
|
closes per-domain command buffers into a submission
|
||||||
|
manages mode transitions
|
||||||
|
keeps only the latest complete submission
|
||||||
|
owns publish/present policy through the render surface
|
||||||
|
```
|
||||||
|
|
||||||
|
O primeiro plano de execucao pode ser incremental:
|
||||||
|
|
||||||
|
1. Definir nomes e contratos dos pacotes sem criar backend registry.
|
||||||
|
2. Migrar o Game 2D path para `Game2DFramePacket -> Classic2D`.
|
||||||
|
3. Manter comportamento pixel-level identico.
|
||||||
|
4. Em seguida migrar Prometeu UI para `UiFramePacket -> Classic2D`.
|
||||||
|
5. So depois discutir outros backends, render thread ou 3D.
|
||||||
|
|
||||||
|
Se quisermos reduzir ainda mais risco, a decisao pode determinar que o primeiro PR implementa apenas o Game 2D packet, mas ja reserva a arquitetura e nomes para `UiFramePacket`. O importante e nao fingir que Prometeu UI e apenas "mais primitives gfx" dentro do pipeline de jogo.
|
||||||
|
|
||||||
|
## Riscos
|
||||||
|
|
||||||
|
- **Abstracao comum errada:** um command set universal pode parecer simples agora, mas virar bloqueio para UI e 3D depois.
|
||||||
|
- **Escopo grande demais:** migrar Game 2D, UI, firmware screens e host presentation em um unico PR aumenta risco de regressao visual.
|
||||||
|
- **Dual path permanente:** se `gfx_mut()` continuar como escape hatch normal, a fronteira de comandos nao vira contrato real.
|
||||||
|
- **Ownership/lifetime dos pacotes:** pacotes borrowed reduzem copia no v1; pacotes owned ajudam render thread futura. A decisao precisa declarar o alvo do primeiro passo.
|
||||||
|
- **HUD ambiguo:** HUD de jogo e UI do Prometeu precisam ficar separados por contrato, mesmo que ambos sejam 2D.
|
||||||
|
- **Present/publication:** `present()` precisa ser tratado como publicacao de superficie, nao como parte aleatoria de cada produtor logico.
|
||||||
|
- **Asset/cache leakage:** command packets devem referenciar recursos logicos/resolvidos sem copiar asset pipeline nem expor detalhes demais do `Gfx`.
|
||||||
|
- **Paralelismo futuro:** se o packet v1 depender de estado mutavel vivo da VM/hardware, uma render thread futura exigira nova quebra arquitetural. A submissao precisa parecer um snapshot fechado mesmo quando consumida sincronicamente no v1.
|
||||||
|
- **Transicoes entre modos:** se Shell e Game forem totalmente independentes sem uma coordenacao mestre, efeitos de transicao e manutencao de superficie ficam sem dono claro.
|
||||||
|
- **Backpressure:** render futuro nao deve acumular fila infinita. A politica aceita e manter somente a submissao completa mais recente.
|
||||||
|
- **Abstracao vs host:** `RenderManager` deve ser contrato runtime/abstracao de coordenacao. Host desktop/render surface deve ser implementacao local separada, sem vazar detalhes para os pipelines.
|
||||||
|
- **HUD ownership:** HUD nao deve ficar escondido dentro de `Gfx2D`. `Gfx2D` deve conter apenas primitivas. No v1, HUD pertence explicitamente ao `composer`.
|
||||||
|
|
||||||
|
## Arquivos / Areas Provavelmente Afetados em uma Plan Futura
|
||||||
|
|
||||||
|
Nucleo Game 2D:
|
||||||
|
|
||||||
|
- `crates/console/prometeu-hal/src/` para tipos compartilhados de packet/submission, se virarem contrato de hardware.
|
||||||
|
- `crates/console/prometeu-hal/src/lib.rs` para exportar novos modulos.
|
||||||
|
- `crates/console/prometeu-drivers/src/frame_composer.rs` para produzir `Game2DFramePacket`.
|
||||||
|
- `crates/console/prometeu-drivers/src/gfx.rs` para consumir `Game2DFramePacket` no Classic2D atual.
|
||||||
|
- `crates/console/prometeu-drivers/src/hardware.rs` para conectar pipeline/submission/implementacao.
|
||||||
|
- `crates/console/prometeu-hal/src/hardware_bridge.rs` para reduzir acesso direto a `GfxBridge` no fluxo de frame.
|
||||||
|
|
||||||
|
Nucleo Prometeu UI:
|
||||||
|
|
||||||
|
- `crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs`
|
||||||
|
- `crates/console/prometeu-system/src/services/windows/*`
|
||||||
|
- `crates/console/prometeu-firmware/src/firmware/firmware_step_splash_screen.rs`
|
||||||
|
- `crates/console/prometeu-firmware/src/firmware/firmware_step_crash_screen.rs`
|
||||||
|
- possivelmente um novo modulo de UI commands em `prometeu-hal` ou `prometeu-system`.
|
||||||
|
|
||||||
|
Possivel, mas deve ser minimizado no primeiro passo:
|
||||||
|
|
||||||
|
- `crates/console/prometeu-system/src/services/vm_runtime/dispatch.rs` se `gfx.*` primitives forem convertidas em command submission.
|
||||||
|
- `crates/console/prometeu-hal/src/gfx_bridge.rs` se a ponte antiga for estreitada.
|
||||||
|
- `crates/host/prometeu-host-desktop-winit/src/runner.rs` se o acesso ao framebuffer for encapsulado, mas host presentation idealmente fica igual no v1.
|
||||||
|
|
||||||
|
## Perguntas em Aberto
|
||||||
|
|
||||||
|
- [x] O primeiro plano deve implementar Game 2D e Prometeu UI juntos, ou apenas Game 2D com contrato preparado para UI?
|
||||||
|
- Resposta: faseado. O primeiro plano deve priorizar Game 2D, mas o contrato deve nomear Prometeu UI como pipeline separado desde o inicio.
|
||||||
|
- [x] O contrato comum deve ser um enum `RenderSubmission`, uma trait de submissao, ou uma fila tipada por pipeline?
|
||||||
|
- Resposta: `AppMode` e `RenderSubmission` devem andar juntos. `AppMode::Game` e `AppMode::Shell` podem ter cadencias e pipelines diferentes; alguns renderers pertencem a um modo e nao ao outro. O envelope inicial pode ser um `RenderSubmission` tipado por modo/pipeline, sem registry dinamico.
|
||||||
|
- [x] `Game2DFramePacket` deve incluir HUD de jogo no v1 ou apenas reservar o campo?
|
||||||
|
- Resposta: deve incluir HUD de jogo no v1. O pipeline 2D de jogos abrange scene, sprites e HUD.
|
||||||
|
- [x] `UiFramePacket` deve representar UI em comandos baixos (`rect`, `text`, `clip`) ou em comandos mais semanticos (`window`, `panel`, `button`)?
|
||||||
|
- Resposta: comandos de UI podem ser diferentes dos comandos Game 2D, mas widget/layout deve ficar fora da implementacao do host. No host, `UiFramePacket` pode ser reduzido a diretivas semelhantes ou equivalentes as primitivas finais de desenho.
|
||||||
|
- [x] Pacotes v1 devem ser borrowed, owned, ou hibridos?
|
||||||
|
- Resposta: hibridos. O modelo precisa suportar transicoes de modo, como clicar no jogo, sair da UI, abrir o jogo e alternar entre `Game` e `Shell`, sem exigir copia pesada de todo recurso.
|
||||||
|
- [x] Onde fica `present()` no novo modelo: no hardware/render surface, no consumidor Classic2D, ou temporariamente no firmware?
|
||||||
|
- Resposta: `present()` pertence a implementacao de hardware/render surface quando ela precisa publicar/trocar buffers. Ele faz sentido em um blit/double-buffer path como Game 2D, mas nao deve ser parte obrigatoria do path canonico de todos os pipelines.
|
||||||
|
- [x] O acesso publico a `gfx.*` deve virar submissao de comandos, ser mantido como debug overlay temporario, ou ser separado em outra discussao?
|
||||||
|
- Resposta: separar apenas as primitivas de desenho por contrato de pipeline. O que ja e `composer.*` deve continuar no dominio `composer`, porque scene, camera, sprites, HUD e orquestracao de frame sao um contrato mais alto nivel do Game 2D, nao primitivas `gfx2d`. `Gfx2D` deve conter somente primitivas. O atual `gfx.*` deve ser dividido em primitivas apropriadas para Game e Shell, por exemplo `gfx2d.*` para primitivas do Game 2D e `gfxui.*` para Prometeu UI/Shell. As stdlibs podem continuar expondo nomes de alto nivel como `gfx`, desde que apontem para syscalls diferentes por `AppMode`.
|
||||||
|
- [x] A agenda aberta `DSC-0011` de dirty regions deve depender desta fronteira antes de continuar?
|
||||||
|
- Resposta: sim. `DSC-0011` vem depois desta fronteira, para nao otimizar o acoplamento errado.
|
||||||
|
- [x] O v1 precisa implementar render thread?
|
||||||
|
- Resposta: nao. Mas o v1 deve preparar a fronteira para isso: `RenderSubmission` deve ser um snapshot fechado por `frame_id`/`AppMode`, sem exigir `&mut Hardware` ou framebuffer mutavel no produtor logico. O consumo pode continuar sincrono na primeira implementacao.
|
||||||
|
- [x] Quem e dono do frame builder?
|
||||||
|
- Resposta: cada dominio/pipeline deve ter seus proprios buffers de comando/estado. O fechamento do frame deve ser centralizado no host/render coordinator, que transforma esses buffers na `RenderSubmission` valida para o `AppMode` atual.
|
||||||
|
- [x] Qual e a ordem de composicao Game 2D?
|
||||||
|
- Resposta: scene e sprites intercalam por `layer` inteiro usando os 4 layers disponiveis do Game 2D, normalmente como `sprite -> scene -> sprite -> scene -> ...` conforme ordenacao por layer. Depois vem um layer de HUD sobre tudo e entao publish. Transicoes visuais devem pertencer ao `RenderManager`, nao ao Game 2D frame path.
|
||||||
|
- [x] Como lidar com transicoes Game/Shell?
|
||||||
|
- Resposta: a arquitetura precisa de um `RenderManager` acima dos pipelines. Ele gerencia troca de modo, manutencao da superficie, capacidades ativas e transicoes que nao pertencem integralmente nem ao Shell UI nem ao Game 2D.
|
||||||
|
- [x] Qual politica de backpressure para render paralelo futuro?
|
||||||
|
- Resposta: sem fila infinita. Manter somente a submissao completa mais recente.
|
||||||
|
- [x] Capabilities devem ser separadas?
|
||||||
|
- Resposta: sim. O contrato deve prever capabilities separadas para `composer`, `gfx2d` e `gfxui`, reforcando o isolamento por `AppMode`.
|
||||||
|
- [x] O host debug overlay deve continuar?
|
||||||
|
- Resposta: nao como parte desta arquitetura. O overlay atual pode ser removido por completo em uma execucao futura; se um console/debug UI voltar a ser necessario, deve ser rediscutido como produto proprio, nao como overlay host-owned herdado.
|
||||||
|
- [x] Fade deve permanecer em algum contrato?
|
||||||
|
- Resposta: nao. Fade deve sair completamente. Ele era uma ideia de hardware inicial e nao deve permanecer como campo de packet, syscall ou habito de implementacao. Transicoes visuais futuras pertencem ao `RenderManager`, nao a `composer`, `gfx2d` ou `gfxui`.
|
||||||
|
- [x] HUD deve ser dominio proprio ou parte do `composer`?
|
||||||
|
- Resposta: HUD fica dentro de `composer` no v1, por ser parte alta do frame Game 2D junto de scene, camera e sprites. `Gfx2D` continua limitado a primitivas.
|
||||||
|
|
||||||
|
## Criterio para Encerrar
|
||||||
|
|
||||||
|
Esta agenda pode virar decisao quando houver consenso sobre:
|
||||||
|
|
||||||
|
- quais pipelines existem no v1;
|
||||||
|
- qual command set pertence ao Game 2D;
|
||||||
|
- qual command set pertence a Prometeu UI;
|
||||||
|
- qual e a fronteira comum entre pipeline e implementacao de hardware/superficie;
|
||||||
|
- o que fica explicitamente fora de escopo;
|
||||||
|
- estrategia de migracao incremental sem mudanca visual;
|
||||||
|
- testes de equivalencia esperados.
|
||||||
|
|
||||||
|
## Discussion
|
||||||
|
|
||||||
|
Atualizacao de 2026-05-25:
|
||||||
|
|
||||||
|
O foco nao deve ser apenas "introduzir `RenderFramePacket` para Classic2D". O foco deve ser separar pipelines logicos por dominio. Game 2D e Prometeu UI podem ter modelos de comando distintos, mas ambos devem submeter comandos a uma implementacao de hardware/render surface.
|
||||||
|
|
||||||
|
A menor refatoracao segura provavelmente continua partindo do Game 2D, porque `FrameComposer` ja concentra scene/cache/sprites. Mas a decisao deve nomear Prometeu UI como pipeline separado desde agora, para evitar que a UI do sistema vire uma extensao acidental do pipeline de jogo.
|
||||||
|
|
||||||
|
Respostas fechadas em discussao:
|
||||||
|
|
||||||
|
- `AppMode::Game` e `AppMode::Shell` continuam sendo os modos canonicos atuais; nao ha rename para `System`.
|
||||||
|
- `RenderSubmission` deve ser coerente com `AppMode`, porque a atualizacao de frame e os renderers disponiveis podem diferir entre Game e Shell.
|
||||||
|
- `composer.*` deve continuar representando scene, camera, sprites, HUD e orquestracao de frame do Game 2D.
|
||||||
|
- `Gfx2D` deve representar apenas primitivas/drawing commands do pipeline Game 2D.
|
||||||
|
- `GfxUI` deve representar primitivas/drawing commands do pipeline Prometeu UI/Shell.
|
||||||
|
- As stdlibs PBS de Game e Shell podem usar nomes parecidos em alto nivel, inclusive `gfx`, mas devem mapear para dominios ABI diferentes conforme `AppMode`.
|
||||||
|
- O host/render implementation pode reduzir command sets diferentes a diretivas locais parecidas, mas widget/layout nao deve morar no host.
|
||||||
|
- `present()` e publicacao de superficie, nao parte obrigatoria de todo pipeline logico.
|
||||||
|
- `DSC-0011` deve aguardar esta fronteira.
|
||||||
|
- Render thread futura nao deve ser implementada agora, mas a fronteira deve nascer compativel com VM e renderer rodando em paralelo: submissions fechadas, leitura imutavel de recursos compartilhados e publicacao isolada na render surface.
|
||||||
|
- Buffers de comando/estado devem pertencer aos dominios/pipelines; o fechamento em `RenderSubmission` deve ser centralizado no `RenderManager`.
|
||||||
|
- `RenderManager` e abstracao/runtime contract; host/render-surface implementation e adaptador local separado.
|
||||||
|
- Game 2D intercalara scene e sprites por layer. HUD fica acima de tudo e pertence ao `composer` no v1, ainda com contrato minimo e evolutivo.
|
||||||
|
- Fade sai completamente. Transicoes de entrada/saida entre Shell e Game pertencem ao `RenderManager`.
|
||||||
|
- Backpressure futuro: latest complete submission wins.
|
||||||
|
- Capabilities devem ser separadas para `composer`, `gfx2d` e `gfxui`.
|
||||||
|
- O debug overlay host-owned atual nao deve ser preservado como requisito; pode ser removido quando a execucao chegar nessa area.
|
||||||
|
|
||||||
|
## Resolution
|
||||||
|
|
||||||
|
As perguntas principais de escopo foram respondidas. A agenda ainda precisa ser aceita explicitamente antes de virar decisao normativa.
|
||||||
|
|
||||||
|
## Next Step
|
||||||
|
|
||||||
|
Fechar as perguntas sobre escopo do v1. Se a direcao de dois pipelines logicos for aceita, transformar esta agenda em uma decisao normativa antes de qualquer plan ou alteracao de codigo.
|
||||||
@ -0,0 +1,236 @@
|
|||||||
|
---
|
||||||
|
id: DEC-0030
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: Logical Render Pipeline Command Boundary
|
||||||
|
status: accepted
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_agenda: AGD-0038
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Decision - Logical Render Pipeline Command Boundary
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepted.
|
||||||
|
|
||||||
|
## Contexto
|
||||||
|
|
||||||
|
Prometeu ja concluiu a migracao do framebuffer/runtime para RGBA8888. O proximo passo do renderer nao e introduzir GPU, 3D, multiplos backends, troca dinamica complexa de pipeline ou render thread. O objetivo imediato e criar uma fronteira arquitetural limpa entre:
|
||||||
|
|
||||||
|
- producao logica de comandos de render;
|
||||||
|
- fechamento/publicacao de frame;
|
||||||
|
- coordenacao entre `AppMode::Game` e `AppMode::Shell`;
|
||||||
|
- rasterizacao/publicacao em uma superficie real.
|
||||||
|
|
||||||
|
O estado atual ainda acopla codigo logico ao `Gfx`/framebuffer. `FrameComposer` ja centraliza parte da orquestracao do frame de jogo, mas ainda desenha por `GfxBridge`. Prometeu Hub, shell/system UI, splash/crash e primitivas `gfx.*` tambem acessam desenho imperativo direto. Essa decisao normatiza a nova fronteira de comandos e o papel de cada dominio.
|
||||||
|
|
||||||
|
## Decisao
|
||||||
|
|
||||||
|
Prometeu MUST separar render pipeline logico de render implementation.
|
||||||
|
|
||||||
|
O runtime SHALL introduce a `RenderManager` as the runtime-level render coordination abstraction. `RenderManager` MUST NOT be a host-specific renderer and MUST NOT contain desktop presentation details. Host/render-surface implementations SHALL adapt `RenderManager` submissions to the local hardware or host surface.
|
||||||
|
|
||||||
|
The canonical render flow SHALL be:
|
||||||
|
|
||||||
|
```text
|
||||||
|
domain buffers during logical frame
|
||||||
|
-> RenderManager closes buffers
|
||||||
|
-> RenderSubmission snapshot
|
||||||
|
-> render surface / implementation consumes submission
|
||||||
|
-> RGBA8888 surface publication
|
||||||
|
```
|
||||||
|
|
||||||
|
The v1 logical render domains are:
|
||||||
|
|
||||||
|
- `composer.*` for Game 2D high-level frame composition: scene, camera, sprites, HUD, and Game 2D frame orchestration.
|
||||||
|
- `gfx2d.*` for Game 2D primitives only.
|
||||||
|
- `gfxui.*` for Shell UI primitives.
|
||||||
|
|
||||||
|
The v1 app modes are:
|
||||||
|
|
||||||
|
- `AppMode::Game`, which SHALL route to Game 2D submissions.
|
||||||
|
- `AppMode::Shell`, which SHALL route to Shell UI submissions.
|
||||||
|
|
||||||
|
No `AppMode::System` rename is accepted by this decision.
|
||||||
|
|
||||||
|
`RenderSubmission` MUST be coherent with `AppMode`. The initial submission model SHOULD be a typed envelope rather than a generic universal command list:
|
||||||
|
|
||||||
|
```text
|
||||||
|
RenderSubmission
|
||||||
|
- frame_id
|
||||||
|
- app_mode
|
||||||
|
- packet:
|
||||||
|
- Game2D(Game2DFramePacket)
|
||||||
|
- ShellUi(UiFramePacket)
|
||||||
|
```
|
||||||
|
|
||||||
|
The exact Rust layout may evolve during planning, but the contract MUST preserve typed per-pipeline command sets.
|
||||||
|
|
||||||
|
## Rationale
|
||||||
|
|
||||||
|
Typed command sets preserve domain meaning. Game 2D and Shell UI have different responsibilities and should not be forced into a weak universal command list. A future 3D or custom 2D pipeline should add its own packet rather than reinterpret a 2D/UI command model.
|
||||||
|
|
||||||
|
`RenderManager` is required because mode transitions do not belong completely to either Shell UI or Game 2D. Shell can render an exit transition before launching a game, but once Game mode owns the frame, Shell UI is no longer available to render the entry transition. Therefore transition coordination, surface maintenance, active render capabilities, and frame publication need a manager above individual pipelines.
|
||||||
|
|
||||||
|
Command buffers and submissions must be distinct. Domain buffers are mutable while the logical frame is being built. A `RenderSubmission` is a closed snapshot. This makes future VM/render parallelism possible without requiring a render thread in v1.
|
||||||
|
|
||||||
|
The current fade model is rejected. Fade was a hardware-direction idea that no longer belongs in the Prometeu render contract after RGBA8888. Fade MUST NOT remain as a packet field, syscall, or implementation habit. Future visual transitions belong to `RenderManager`.
|
||||||
|
|
||||||
|
## Invariantes / Contrato
|
||||||
|
|
||||||
|
### Pipeline and Implementation Boundary
|
||||||
|
|
||||||
|
- Pipelines MUST produce logical commands or state.
|
||||||
|
- Render implementations MUST consume submissions and write/publish to a surface.
|
||||||
|
- Pipeline code MUST NOT require direct mutable access to the framebuffer.
|
||||||
|
- Pipeline code MUST NOT depend on host-specific presentation details.
|
||||||
|
|
||||||
|
### RenderManager
|
||||||
|
|
||||||
|
- `RenderManager` MUST coordinate active `AppMode`, submission closure, mode transitions, capabilities, and publication policy.
|
||||||
|
- `RenderManager` MUST be a runtime abstraction, not a host renderer.
|
||||||
|
- Host/render-surface implementations MUST be separate adapters.
|
||||||
|
- `RenderManager` MUST own transition coordination between Game and Shell.
|
||||||
|
- `RenderManager` MUST own the policy for surface publication/present through the render surface.
|
||||||
|
|
||||||
|
### Command Buffers and Submissions
|
||||||
|
|
||||||
|
- Each render domain/pipeline MUST own its own mutable command/state buffer during a logical frame.
|
||||||
|
- `RenderManager` MUST close the active buffers into a `RenderSubmission` at frame boundary.
|
||||||
|
- Once closed, `RenderSubmission` MUST be treated as immutable by producers.
|
||||||
|
- `RenderSubmission` MUST include `frame_id` and `app_mode`.
|
||||||
|
- Future parallel render MUST be supported by the contract: consuming a submission MUST NOT require `&mut Hardware`, `&mut Gfx`, or live mutable VM state.
|
||||||
|
- Backpressure policy MUST be latest-complete-submission-wins. The system MUST NOT accumulate an unbounded frame queue.
|
||||||
|
|
||||||
|
### AppMode Routing
|
||||||
|
|
||||||
|
- `AppMode::Game` SHALL expose and route Game render domains.
|
||||||
|
- `AppMode::Shell` SHALL expose and route Shell UI render domains.
|
||||||
|
- Renderers/capabilities MAY differ by app mode.
|
||||||
|
- PBS stdlibs MAY expose similar high-level names, including `gfx`, but they MUST map to mode-appropriate ABI domains.
|
||||||
|
|
||||||
|
### ABI Domains
|
||||||
|
|
||||||
|
- `composer.*` MUST remain the high-level Game 2D composition domain.
|
||||||
|
- `composer.*` MUST own scene, camera, sprites, HUD, and Game 2D frame orchestration.
|
||||||
|
- `gfx2d.*` MUST contain Game 2D primitives only.
|
||||||
|
- `gfx2d.*` MUST NOT own scene, camera, sprites, HUD, or frame orchestration.
|
||||||
|
- `gfxui.*` MUST contain Shell UI primitives.
|
||||||
|
- `gfxui.*` MUST NOT contain widget/layout policy. Widget/layout belongs in Shell/UI code or stdlib, not the host implementation.
|
||||||
|
- Capabilities MUST be separated for `composer`, `gfx2d`, and `gfxui`.
|
||||||
|
|
||||||
|
### Game 2D Composition
|
||||||
|
|
||||||
|
- Game 2D scene and sprites MUST compose by integer `layer`.
|
||||||
|
- The v1 Game 2D model has four available layers.
|
||||||
|
- Scene and sprite composition MAY interleave by layer, normally as sprite/scene ordering across the four layers.
|
||||||
|
- HUD MUST render above scene/sprite composition.
|
||||||
|
- HUD belongs to `composer` in v1 and remains a minimal, evolvable contract.
|
||||||
|
- HUD in this decision means Game HUD only. Shell/system UI is always part of the Shell UI pipeline.
|
||||||
|
- Game 2D publish happens after scene/sprite/HUD composition.
|
||||||
|
|
||||||
|
### Shell UI Composition
|
||||||
|
|
||||||
|
- Shell UI MUST use its own `gfxui.*` primitive command set.
|
||||||
|
- Shell UI commands MAY reduce to the same local drawing directives as Game 2D primitives inside a host/render-surface implementation.
|
||||||
|
- That reduction MUST remain an implementation detail and MUST NOT collapse the ABI domains.
|
||||||
|
|
||||||
|
### Fade and Transitions
|
||||||
|
|
||||||
|
- Fade MUST be removed completely from canonical pipeline contracts.
|
||||||
|
- Fade MUST NOT appear as a `Game2DFramePacket`, `UiFramePacket`, `RenderSubmission`, `composer`, `gfx2d`, or `gfxui` field or syscall.
|
||||||
|
- Future visual transitions MUST be coordinated by `RenderManager`.
|
||||||
|
|
||||||
|
### Debug Overlay
|
||||||
|
|
||||||
|
- The current host-owned debug overlay is not part of the new render architecture.
|
||||||
|
- It MAY be removed during execution.
|
||||||
|
- A future console/debug UI MUST be discussed as a separate product/domain, not preserved as inherited host overlay behavior.
|
||||||
|
|
||||||
|
## Impactos
|
||||||
|
|
||||||
|
### Spec
|
||||||
|
|
||||||
|
Specs must define the logical render pipeline model, `RenderManager`, `RenderSubmission`, app-mode routing, domain buffers, and publication boundary in English.
|
||||||
|
|
||||||
|
The public syscall/ABI specs must replace the old primitive `gfx.*` surface with mode-appropriate `gfx2d.*` and `gfxui.*` primitive domains while preserving `composer.*` as the high-level Game 2D composition domain.
|
||||||
|
|
||||||
|
### Runtime
|
||||||
|
|
||||||
|
Runtime frame execution must stop treating `Gfx`/framebuffer as the direct target of logical render calls. It must accumulate domain state/commands and let `RenderManager` close submissions.
|
||||||
|
|
||||||
|
`VirtualMachineRuntime` and firmware flow must route frame closure through `RenderManager`.
|
||||||
|
|
||||||
|
### HAL
|
||||||
|
|
||||||
|
HAL must expose distinct contracts for:
|
||||||
|
|
||||||
|
- `composer`;
|
||||||
|
- `gfx2d`;
|
||||||
|
- `gfxui`;
|
||||||
|
- render submissions;
|
||||||
|
- render manager/surface boundary.
|
||||||
|
|
||||||
|
Capability flags must be split accordingly.
|
||||||
|
|
||||||
|
### Host
|
||||||
|
|
||||||
|
The desktop host remains a concrete render-surface implementation. It may continue publishing RGBA8888 to `pixels`, but that behavior must sit below the render-surface adapter, not inside logical pipeline APIs.
|
||||||
|
|
||||||
|
Host debug overlay may be removed.
|
||||||
|
|
||||||
|
### Firmware / Shell
|
||||||
|
|
||||||
|
Shell UI must migrate away from direct `gfx_mut()` drawing toward `gfxui.*`/Shell UI command buffers.
|
||||||
|
|
||||||
|
Game mode must migrate toward `composer.*` plus `gfx2d.*` buffers closed by `RenderManager`.
|
||||||
|
|
||||||
|
### PBS / Stdlibs
|
||||||
|
|
||||||
|
PBS Game and Shell stdlibs may present similar high-level APIs to authors. They must map to different ABI domains according to `AppMode`.
|
||||||
|
|
||||||
|
Game stdlib should map scene/camera/sprites/HUD to `composer.*` and primitive Game drawing to `gfx2d.*`.
|
||||||
|
|
||||||
|
Shell stdlib should map UI primitives to `gfxui.*`.
|
||||||
|
|
||||||
|
## Alternativas Descartadas
|
||||||
|
|
||||||
|
### Universal RenderCommand
|
||||||
|
|
||||||
|
A single `RenderCommand` display list for Game, Shell, and future pipelines is rejected. It collapses domain meaning and would likely force future 3D or custom pipelines into a 2D/UI-shaped contract.
|
||||||
|
|
||||||
|
### Trait-Only RenderPipeline
|
||||||
|
|
||||||
|
A trait that calls `render(&mut Surface)` without a closed packet is rejected as the primary boundary. It preserves immediate rendering and does not prepare VM/render parallelism.
|
||||||
|
|
||||||
|
### Backend Registry Now
|
||||||
|
|
||||||
|
A full backend registry, GPU/CPU backend abstraction, dynamic pipeline switching, render thread, or 3D implementation is out of scope. Those may come later after the command boundary is stable.
|
||||||
|
|
||||||
|
### Moving Composer into Gfx2D
|
||||||
|
|
||||||
|
Moving scene, camera, sprites, HUD, or frame orchestration into `gfx2d.*` is rejected. `gfx2d.*` is primitives only.
|
||||||
|
|
||||||
|
## Referencias
|
||||||
|
|
||||||
|
- Agenda: `AGD-0038`
|
||||||
|
- Related dependency: `DSC-0011` dirty regions must wait until this boundary exists.
|
||||||
|
- Related prior lessons: frame composition belongs above the render backend; public ABI must follow canonical service boundaries; RGBA8888 is the canonical framebuffer contract.
|
||||||
|
|
||||||
|
## Propagacao Necessaria
|
||||||
|
|
||||||
|
- Create a plan before any spec or code changes.
|
||||||
|
- Update canonical specs in English.
|
||||||
|
- Update HAL syscall registry, capability definitions, and resolver tests.
|
||||||
|
- Update PBS/stdlib syscall declarations for Game and Shell.
|
||||||
|
- Update runtime dispatch so render syscalls mutate domain buffers instead of drawing directly.
|
||||||
|
- Introduce `RenderManager`, domain buffers, `RenderSubmission`, and render-surface implementation boundary.
|
||||||
|
- Migrate Game 2D first, then Shell UI, unless the plan proves both can be safely migrated together.
|
||||||
|
- Remove fade surfaces from render contracts.
|
||||||
|
- Remove or explicitly retire the host debug overlay.
|
||||||
|
- Add packet/submission tests, app-mode capability tests, and pixel-equivalence tests for unchanged visible behavior.
|
||||||
|
|
||||||
|
## Revision Log
|
||||||
|
|
||||||
|
- 2026-05-25: Initial decision draft from `AGD-0038`.
|
||||||
67
discussion/workflow/plans/PLN-0073-render-contract-specs.md
Normal file
67
discussion/workflow/plans/PLN-0073-render-contract-specs.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0073
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: Render Contract Specs
|
||||||
|
status: done
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Publish canonical English spec language for the logical render pipeline boundary before code migration. The specs must make `RenderManager`, domain buffers, typed `RenderSubmission`, app-mode routing, render-surface publication, latest-complete-submission policy, and fade removal explicit.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
Canonical specs describe the DEC-0030 render contract well enough that HAL, runtime, host, firmware, and PBS work can proceed without reopening architecture.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Define the logical flow from mutable domain buffers to closed `RenderSubmission` to render-surface publication.
|
||||||
|
- Define `RenderManager` as runtime coordination, not a host renderer.
|
||||||
|
- Define `RenderSubmission` with `frame_id`, `app_mode`, and typed Game 2D or Shell UI packet.
|
||||||
|
- Define `composer.*`, `gfx2d.*`, and `gfxui.*` as separate ABI domains.
|
||||||
|
- Specify latest-complete-submission-wins backpressure.
|
||||||
|
- Remove fade from canonical render contracts.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Rust implementation.
|
||||||
|
- PBS stdlib implementation.
|
||||||
|
- Pixel output changes.
|
||||||
|
- Backend registry, GPU backend, render thread, 3D pipeline, or debug console design.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Inventory existing render, graphics, framebuffer, composer, and syscall specs.
|
||||||
|
2. Replace old primitive `gfx.*` ABI language with the DEC-0030 domain split.
|
||||||
|
3. Add sections for `RenderManager`, domain buffers, submission closure, immutability, and publication.
|
||||||
|
4. Add app-mode and capability routing language for Game and Shell.
|
||||||
|
5. Remove normative fade fields, syscalls, and packet references from render specs.
|
||||||
|
6. Cross-link impacted specs for HAL, runtime, host, firmware, and PBS propagation.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- Specs are in English and reference `DEC-0030`.
|
||||||
|
- No canonical render spec presents direct framebuffer mutation as the logical render API.
|
||||||
|
- No canonical render spec keeps fade as a packet field, syscall, or ABI habit.
|
||||||
|
- Specs distinguish logical pipeline production from render-surface implementation.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Run repository documentation/spec validation if available.
|
||||||
|
- Inspect `rg -n "fade|gfx\\.\\*|RenderSubmission|RenderManager|present\\(" specs discussion/workflow/decisions/DEC-0030-logical-render-pipeline-command-boundary.md`.
|
||||||
|
- Run `discussion validate` if discussion references change.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- Existing specs may use `gfx.*` as both author API and ABI name; preserve author clarity while changing ABI names.
|
||||||
|
- Removing fade text can accidentally delete transition requirements; move those requirements to `RenderManager` language.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- `specs/`
|
||||||
|
- `discussion/workflow/decisions/DEC-0030-logical-render-pipeline-command-boundary.md`
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0074
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: HAL Render Submission Types
|
||||||
|
status: done
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Introduce HAL-level submission types that encode the logical render boundary without binding consumers to live `Hardware`, `Gfx`, framebuffer, or VM state.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
HAL exposes typed contracts for `RenderSubmission`, `Game2DFramePacket`, `ShellUiFramePacket`, frame ids, app-mode routing, and immutable closed submissions.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Add typed packet structures for Game 2D and Shell UI.
|
||||||
|
- Add a `RenderSubmission` envelope with `frame_id`, `app_mode`, and typed packet variant.
|
||||||
|
- Add or reuse a monotonic frame id type.
|
||||||
|
- Encode closed-submission immutability through ownership and API shape.
|
||||||
|
- Keep packet types free of host presentation details and live mutable runtime references.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- `RenderManager` behavior beyond type integration.
|
||||||
|
- Renderer/rasterizer implementation.
|
||||||
|
- Backend registry, render thread, GPU path, or 3D packet.
|
||||||
|
- PBS stdlib updates.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Locate current HAL graphics, composer, capability, and app-mode modules.
|
||||||
|
2. Add packet and submission types where ABI-facing render data belongs.
|
||||||
|
3. Represent packets as typed variants: `Game2D(Game2DFramePacket)` and `ShellUi(ShellUiFramePacket)`.
|
||||||
|
4. Ensure constructors or closure APIs consume or clone domain buffer contents.
|
||||||
|
5. Add tests for app-mode and packet coherence.
|
||||||
|
6. Update internal references to use the new types without changing runtime rendering yet.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- HAL contains the DEC-0030 submission and packet vocabulary.
|
||||||
|
- A closed `RenderSubmission` can be handed to a consumer without borrowing live runtime rendering state.
|
||||||
|
- Game and Shell packets are distinguishable at the type level.
|
||||||
|
- The HAL API does not include fade fields.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Run HAL crate unit tests.
|
||||||
|
- Add tests for packet construction, app-mode coherence, and immutable ownership semantics.
|
||||||
|
- Inspect `rg -n "fade|UiFramePacket|ShellUiFramePacket|Game2DFramePacket|RenderSubmission" crates specs`.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- New types must live at the ABI/contract level, not inside a host renderer.
|
||||||
|
- Borrowing shortcuts could leak mutability and violate the future parallel render contract.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- HAL crate/module under `crates/`
|
||||||
|
- HAL tests
|
||||||
68
discussion/workflow/plans/PLN-0075-rendermanager-core.md
Normal file
68
discussion/workflow/plans/PLN-0075-rendermanager-core.md
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0075
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: RenderManager Core
|
||||||
|
status: open
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Add `RenderManager` as the runtime abstraction that closes domain buffers into typed submissions, tracks active app mode, owns transition coordination placeholders, and hands the latest complete submission to the render surface.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
Runtime frame execution routes render closure through `RenderManager` without making it a host renderer or direct framebuffer writer.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Add the `RenderManager` module and public runtime API.
|
||||||
|
- Track active `AppMode` and frame id generation.
|
||||||
|
- Close the active domain buffer into a `RenderSubmission`.
|
||||||
|
- Enforce latest-complete-submission-wins rather than an unbounded queue.
|
||||||
|
- Add transition coordination placeholders owned by `RenderManager`.
|
||||||
|
- Provide a publication handoff to a render-surface abstraction.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Full visual transition implementation.
|
||||||
|
- Host-specific presentation details.
|
||||||
|
- Domain buffer implementation beyond integration points.
|
||||||
|
- Render thread, GPU backend, or backend registry.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Add a runtime render module that owns `RenderManager` and related state.
|
||||||
|
2. Wire `VirtualMachineRuntime` frame closure through `RenderManager`.
|
||||||
|
3. Add active app-mode routing and rejection for incoherent packet closure.
|
||||||
|
4. Add latest-complete-submission storage and replacement semantics.
|
||||||
|
5. Add a render-surface handoff interface without calling host-specific `present()` from producers.
|
||||||
|
6. Add explicit no-op transition hooks for future work.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- Runtime has one frame closure authority for render submissions.
|
||||||
|
- Producers can mutate domain buffers before closure but cannot mutate the closed submission.
|
||||||
|
- `RenderManager` does not depend on desktop host types.
|
||||||
|
- Backpressure is latest-complete-submission-wins.
|
||||||
|
- App-mode routing is explicit and tested.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Add unit tests for frame id increment, latest submission replacement, app-mode routing, and no-op transition state.
|
||||||
|
- Add runtime integration coverage proving frame closure passes through `RenderManager`.
|
||||||
|
- Run affected crate tests.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- Existing frame lifecycle code may assume immediate framebuffer mutation; isolate compatibility shims and remove them in later plans.
|
||||||
|
- Transition placeholders must not become hidden fade behavior.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- Runtime crate/modules under `crates/`
|
||||||
|
- Runtime tests
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0076
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: Capabilities and ABI Domain Split
|
||||||
|
status: open
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Split render capabilities and syscall metadata so `composer`, `gfx2d`, and `gfxui` are independently addressable and enforceable according to `AppMode`.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
Capability gates reject wrong-domain render syscalls, and metadata no longer treats the old primitive `gfx.*` ABI as the single render surface.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Add or rename capability flags for `COMPOSER`, `GFX2D`, and `GFXUI`.
|
||||||
|
- Update syscall metadata for all render-domain calls.
|
||||||
|
- Enforce domain availability by `AppMode::Game` and `AppMode::Shell`.
|
||||||
|
- Update resolver and capability tests.
|
||||||
|
- Preserve `composer.*` as Game 2D high-level composition.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Implementing command buffers.
|
||||||
|
- PBS stdlib author-facing wrappers.
|
||||||
|
- Host rendering.
|
||||||
|
- Backward compatibility for the old primitive `gfx.*` ABI.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Locate capability definitions, syscall registry metadata, and resolver tests.
|
||||||
|
2. Introduce separate render capability identifiers for `composer`, `gfx2d`, and `gfxui`.
|
||||||
|
3. Update metadata for existing composer calls and new or renamed primitive domains.
|
||||||
|
4. Add app-mode checks so Game exposes `composer` and `gfx2d`, while Shell exposes `gfxui`.
|
||||||
|
5. Replace stale tests that assume one graphics capability.
|
||||||
|
6. Run resolver and runtime syscall tests.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- Wrong-domain calls fail before mutating render state.
|
||||||
|
- Game mode cannot use `gfxui.*`.
|
||||||
|
- Shell mode cannot use `composer.*` or `gfx2d.*`.
|
||||||
|
- Capability metadata uses the split domain names.
|
||||||
|
- No compatibility promise remains for the old primitive `gfx.*` ABI.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Add resolver tests for all three capabilities.
|
||||||
|
- Add app-mode enforcement tests for allowed and rejected calls.
|
||||||
|
- Run affected unit and integration tests.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- A large rename can hide semantic mistakes; verify every syscall maps to the correct domain responsibility.
|
||||||
|
- Author-facing stdlib names may still use `gfx`; keep this plan focused on ABI metadata.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- Syscall metadata and resolver modules under `crates/`
|
||||||
|
- Capability tests
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0077
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: Composer Buffer and Game2D Packet
|
||||||
|
status: open
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Convert current `composer.*` frame state into a mutable `ComposerBuffer` that closes into `Game2DFramePacket` at frame boundary.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
Game 2D scene, camera, sprites, HUD, and frame orchestration are represented as domain-owned state until `RenderManager` closes them into a typed packet.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Add `ComposerBuffer`.
|
||||||
|
- Move scene, camera, sprite, HUD, layer ordering, and Game 2D orchestration state into the buffer.
|
||||||
|
- Close the buffer into `Game2DFramePacket`.
|
||||||
|
- Preserve the v1 four-layer scene/sprite composition model and HUD-above-game rule.
|
||||||
|
- Ensure fade is absent from Game 2D packet state.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Primitive `gfx2d.*` command buffering.
|
||||||
|
- Shell UI packet work.
|
||||||
|
- Renderer consumption refactor beyond packet shape.
|
||||||
|
- New Game 2D features.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Locate current `FrameComposer`, composer syscalls, scene/camera/sprite/HUD state, and tests.
|
||||||
|
2. Introduce `ComposerBuffer` and migrate composer mutation paths into it.
|
||||||
|
3. Implement closure into `Game2DFramePacket` with immutable packet contents.
|
||||||
|
4. Preserve integer layer ordering across the four Game 2D layers and HUD final composition.
|
||||||
|
5. Route frame closure through `RenderManager`.
|
||||||
|
6. Update tests that currently inspect `FrameComposer` internals.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- `composer.*` owns Game 2D high-level frame state.
|
||||||
|
- Closed `Game2DFramePacket` contains all data required by the Game 2D renderer without live VM or `Gfx` access.
|
||||||
|
- Scene/sprite layer behavior and HUD ordering are preserved.
|
||||||
|
- Fade is not represented.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Add unit tests for buffer mutation and packet closure.
|
||||||
|
- Add composition ordering tests for scene, sprites, and HUD.
|
||||||
|
- Run current frame composer/render tests and compare existing expected output.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- Existing composer code may mix orchestration with drawing; split state capture from rendering before deeper migration.
|
||||||
|
- Layer behavior is user-visible and must not drift.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- Composer/frame-composer modules under `crates/`
|
||||||
|
- Game 2D tests
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0078
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: Classic2D Game Renderer Consumer
|
||||||
|
status: open
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Refactor the Classic2D renderer path so it consumes `Game2DFramePacket` instead of being called directly by `FrameComposer` or logical producers.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
Classic2D remains the concrete Game 2D rasterizer, but its input is a closed packet and its visible pixel output remains equivalent.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Add a packet consumer entry point for the current Classic2D/Gfx renderer.
|
||||||
|
- Replace direct `FrameComposer` to `Gfx` calls with packet consumption.
|
||||||
|
- Keep RGBA8888 output unchanged for existing supported scenes.
|
||||||
|
- Keep renderer implementation below the logical pipeline boundary.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Redesigning scene, sprite, HUD, or primitive semantics.
|
||||||
|
- Shell UI rendering.
|
||||||
|
- Backend registry or GPU work.
|
||||||
|
- Dirty region optimization.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Locate the current Classic2D/Gfx rendering entry points and `FrameComposer` call graph.
|
||||||
|
2. Add a `Game2DFramePacket` consumer API.
|
||||||
|
3. Move rendering reads from live composer state to packet data.
|
||||||
|
4. Update frame execution to pass the closed packet into the renderer through the render surface path.
|
||||||
|
5. Preserve existing framebuffer dimensions, RGBA8888 format, and pixel behavior.
|
||||||
|
6. Remove direct producer-to-renderer calls that bypass the packet boundary.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- Classic2D renders from `Game2DFramePacket`.
|
||||||
|
- Logical composer code no longer directly mutates `Gfx` during frame production.
|
||||||
|
- Existing Game 2D visual fixtures or tests remain pixel-equivalent except where explicitly updated for the new boundary.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Add packet-to-pixels tests for representative scene, sprite, primitive, and HUD cases.
|
||||||
|
- Run existing render tests.
|
||||||
|
- Add regression coverage comparing old expected pixel buffers where available.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- Packet conversion can accidentally alter draw order; keep tests focused on ordering and final pixels.
|
||||||
|
- Some current code may depend on side effects from direct `Gfx` mutation; identify and replace those effects explicitly.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- Classic2D/Gfx renderer modules under `crates/`
|
||||||
|
- Render tests and fixtures
|
||||||
66
discussion/workflow/plans/PLN-0079-gfx2d-primitive-domain.md
Normal file
66
discussion/workflow/plans/PLN-0079-gfx2d-primitive-domain.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0079
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: Gfx2D Primitive Domain
|
||||||
|
status: open
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Replace primitive Game drawing paths with `gfx2d.*` command buffering while keeping `gfx2d` limited to primitives only.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
Game primitive drawing becomes a Game-mode ABI domain that records commands into a buffer consumed as part of Game 2D rendering.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Add `gfx2d.*` syscall domain and command buffer.
|
||||||
|
- Migrate primitive Game drawing calls from old `gfx.*` behavior to `gfx2d.*`.
|
||||||
|
- Ensure `gfx2d` contains primitives only.
|
||||||
|
- Integrate `gfx2d` commands into the Game 2D packet/render path without taking ownership of scene, camera, sprites, HUD, or frame orchestration.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Shell UI primitive domain.
|
||||||
|
- `composer.*` high-level Game state.
|
||||||
|
- Widget/layout policy.
|
||||||
|
- Compatibility with old primitive `gfx.*` ABI names.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Inventory old primitive `gfx.*` syscalls and direct drawing callsites used by Game mode.
|
||||||
|
2. Define the `gfx2d.*` command enum and mutable command buffer.
|
||||||
|
3. Route Game primitive syscalls into the buffer.
|
||||||
|
4. Add app-mode and capability enforcement for Game-only access.
|
||||||
|
5. Integrate buffered primitives into Game 2D packet closure or renderer consumption at the DEC-0030-approved layer.
|
||||||
|
6. Remove or retire old primitive `gfx.*` ABI registrations.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- Game primitive commands are buffered as `gfx2d.*`.
|
||||||
|
- `gfx2d` does not own scene, camera, sprites, HUD, or frame orchestration.
|
||||||
|
- Shell mode cannot call `gfx2d.*`.
|
||||||
|
- No logical primitive path directly mutates framebuffer during production.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Add syscall tests for each migrated primitive.
|
||||||
|
- Add command buffer ordering tests.
|
||||||
|
- Add capability rejection tests for Shell mode.
|
||||||
|
- Run pixel-equivalence tests for unchanged primitive output.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- The old `gfx` naming may appear in PBS wrappers; distinguish author API names from ABI domain names.
|
||||||
|
- Primitive ordering relative to composer output must be explicit.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- Syscall registry and runtime render domain modules under `crates/`
|
||||||
|
- Game primitive tests
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0080
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: Shell UI Packet and GfxUI Domain
|
||||||
|
status: open
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Add `gfxui.*` command buffering and `ShellUiFramePacket` for Shell UI primitives while keeping widget/layout policy outside the host/render-surface implementation.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
Shell UI emits typed UI primitive commands into a Shell-only packet that render-surface implementations can consume without collapsing UI and Game ABI domains.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Define `gfxui.*` primitive commands.
|
||||||
|
- Add a mutable Shell UI command buffer.
|
||||||
|
- Close Shell UI commands into `ShellUiFramePacket`.
|
||||||
|
- Enforce Shell-only capability and app-mode access.
|
||||||
|
- Keep widget/layout policy in Shell/UI code or stdlib layers.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Migrating all Shell callsites; that is handled by the Shell/Hub migration plan.
|
||||||
|
- Game primitive rendering.
|
||||||
|
- New widget framework.
|
||||||
|
- Host-owned debug overlay.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Define the `gfxui.*` syscall and command vocabulary needed for current Shell UI primitives.
|
||||||
|
2. Add a Shell UI command buffer and closure into `ShellUiFramePacket`.
|
||||||
|
3. Add capability metadata and resolver enforcement for `GFXUI`.
|
||||||
|
4. Add a render-surface consumer path that can rasterize Shell UI commands as an implementation detail.
|
||||||
|
5. Keep layout/widget decisions above the packet boundary.
|
||||||
|
6. Add tests for closure, app-mode gating, and packet consumption.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- Shell UI commands close into `ShellUiFramePacket`.
|
||||||
|
- `gfxui.*` does not contain widget/layout policy.
|
||||||
|
- Game mode cannot call `gfxui.*`.
|
||||||
|
- Host/render-surface code consumes commands without redefining Shell UI product policy.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Add Shell UI command buffer unit tests.
|
||||||
|
- Add app-mode rejection tests for Game mode.
|
||||||
|
- Add render-surface consumer tests for representative primitives.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- It is easy to migrate widget policy into host rendering while adding UI primitives; keep commands low-level and policy-free.
|
||||||
|
- Shell UI and Game primitives may rasterize similarly, but ABI domains must remain distinct.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- Shell UI render domain modules under `crates/`
|
||||||
|
- Syscall metadata and tests
|
||||||
67
discussion/workflow/plans/PLN-0081-shell-hub-migration.md
Normal file
67
discussion/workflow/plans/PLN-0081-shell-hub-migration.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0081
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: Shell Hub Migration
|
||||||
|
status: open
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Move Prometeu Hub, shell windows, splash/crash UI, and Shell drawing away from `gfx_mut()` into `gfxui.*` and Shell UI command buffers.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
Shell-facing UI no longer draws directly into `Gfx`; it produces Shell UI commands that close into `ShellUiFramePacket`.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Migrate Prometeu Hub UI drawing.
|
||||||
|
- Migrate shell windows and window-manager drawing.
|
||||||
|
- Migrate splash and crash UI drawing.
|
||||||
|
- Remove direct Shell access to `gfx_mut()` for render production.
|
||||||
|
- Preserve visible Shell output where behavior is not intentionally changed.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Designing new Hub visuals.
|
||||||
|
- New widget/layout framework.
|
||||||
|
- Game mode migration.
|
||||||
|
- Debug console replacement.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Inventory Shell, Hub, splash, crash, and firmware drawing callsites that use `gfx_mut()` or direct framebuffer access.
|
||||||
|
2. Replace direct primitive drawing with `gfxui.*` buffer writes.
|
||||||
|
3. Route Shell frame closure through `RenderManager`.
|
||||||
|
4. Ensure Shell UI packets are consumed by the render-surface implementation.
|
||||||
|
5. Remove now-unused direct Shell rendering hooks.
|
||||||
|
6. Update tests and snapshots for unchanged visible behavior.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- Shell UI production no longer requires mutable `Gfx` access.
|
||||||
|
- Hub, shell windows, splash, and crash UI can render through `ShellUiFramePacket`.
|
||||||
|
- Shell mode does not use `composer.*` or `gfx2d.*`.
|
||||||
|
- Visible UI output is preserved except for approved fixture updates caused by boundary-only refactoring.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Add integration tests for Hub/shell frame production.
|
||||||
|
- Add tests for splash and crash UI packet output.
|
||||||
|
- Run host smoke tests where available.
|
||||||
|
- Use pixel or snapshot comparisons for representative Shell screens.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- Firmware and Shell code may mix lifecycle side effects with drawing; split command production without changing lifecycle semantics.
|
||||||
|
- Some host tests may assume immediate framebuffer writes; update them to observe submissions or final pixels.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- Shell, Hub, firmware, and host integration modules under `crates/`
|
||||||
|
- Shell UI tests and fixtures
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0082
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: Frame Publication and Present Boundary
|
||||||
|
status: open
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Move `present()` and surface publication behind the render-surface implementation boundary so runtime producers no longer publish buffers directly.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
Only the render-surface implementation publishes RGBA8888 output; logical producers and `RenderManager` hand off closed submissions through a boundary.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Identify all direct `present()` and surface publication callsites.
|
||||||
|
- Define the render-surface adapter boundary.
|
||||||
|
- Route publication through the adapter from `RenderManager`.
|
||||||
|
- Keep desktop `pixels` publication as a host implementation detail.
|
||||||
|
- Preserve frame pacing and invalidation behavior.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- New backend registry.
|
||||||
|
- GPU implementation.
|
||||||
|
- Render thread.
|
||||||
|
- Dirty regions.
|
||||||
|
- Visual transition design.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Inventory `present()`, framebuffer publication, and host invalidation callsites.
|
||||||
|
2. Add or refine a render-surface trait/adapter that consumes `RenderSubmission`.
|
||||||
|
3. Move host desktop publication below that adapter.
|
||||||
|
4. Update runtime frame loop to publish only through `RenderManager` and the adapter.
|
||||||
|
5. Remove direct publication from composer, `gfx2d`, `gfxui`, Shell, and Game producers.
|
||||||
|
6. Verify frame pacing and host invalidation still occur at the correct boundary.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- Logical render domains cannot call `present()` or publish buffers directly.
|
||||||
|
- Host desktop publication remains functional below the render-surface boundary.
|
||||||
|
- `RenderManager` owns the policy for selecting the latest complete submission.
|
||||||
|
- Existing frame pacing behavior is not regressed.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Add unit tests for render-surface handoff.
|
||||||
|
- Add integration tests proving producers cannot publish directly.
|
||||||
|
- Run host desktop render/pacing tests.
|
||||||
|
- Inspect `rg -n "present\\(|publish|pixels" crates` for boundary violations.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- Publication and invalidation may be coupled in current host code; preserve timing semantics while moving ownership.
|
||||||
|
- A too-broad adapter can become a backend registry prematurely.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- Runtime render manager modules
|
||||||
|
- Host desktop render surface modules
|
||||||
|
- Frame pacing tests
|
||||||
63
discussion/workflow/plans/PLN-0083-fade-removal.md
Normal file
63
discussion/workflow/plans/PLN-0083-fade-removal.md
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0083
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: Fade Removal
|
||||||
|
status: open
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Remove fade fields, syscalls, packet members, renderer state, tests, and docs from canonical render contracts.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
Fade is no longer a render pipeline feature. Future visual transitions remain the responsibility of `RenderManager` and require separate product/domain work.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Remove fade from specs, HAL packet types, syscall metadata, runtime state, renderer state, tests, and PBS declarations.
|
||||||
|
- Remove or update tests that assert fade behavior.
|
||||||
|
- Add guard tests or searches that prevent reintroducing fade in canonical render contracts.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Implementing replacement visual transitions.
|
||||||
|
- Replacing fade with another transition API.
|
||||||
|
- Preserving backward compatibility for fade syscalls.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Inventory all fade references in specs, crates, tests, examples, and PBS stdlibs.
|
||||||
|
2. Delete fade fields and syscalls from canonical ABI and packet definitions.
|
||||||
|
3. Remove renderer/runtime fade state and behavior.
|
||||||
|
4. Update callers and tests to stop setting or expecting fade.
|
||||||
|
5. Add documentation language that transitions belong to `RenderManager`.
|
||||||
|
6. Run targeted and full affected tests.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- No canonical packet, syscall, or render contract contains fade.
|
||||||
|
- Runtime and renderer code do not maintain fade state.
|
||||||
|
- Tests no longer depend on fade behavior.
|
||||||
|
- Specs clearly state future transitions are `RenderManager` responsibility.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Run `rg -n "\\bfade\\b|Fade" specs crates discussion/workflow` and verify remaining references are only historical decision/agenda text or explicit removal notes.
|
||||||
|
- Run affected unit and integration tests.
|
||||||
|
- Add regression tests preventing fade fields in current packet types.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- Removing tests can reduce coverage; replace fade-specific assertions with packet/transition boundary assertions where appropriate.
|
||||||
|
- Historical discussion files may keep fade references; do not rewrite history unless the framework requires it.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- Specs
|
||||||
|
- HAL, runtime, renderer, syscall, PBS, and tests under `crates/`
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0084
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: Host Debug Overlay Removal
|
||||||
|
status: open
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Remove the current host-owned debug overlay from the render path. Any future console/debug UI is a separate product/domain discussion.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
Host rendering no longer injects an inherited debug overlay into Game or Shell output.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Identify host-owned debug overlay code and render hooks.
|
||||||
|
- Remove overlay rendering from the host render path.
|
||||||
|
- Remove overlay toggles/tests that assume inherited host drawing.
|
||||||
|
- Preserve non-render telemetry and logging where they are not tied to overlay drawing.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Designing a replacement debug console.
|
||||||
|
- Moving debug UI into `gfxui.*`.
|
||||||
|
- Changing telemetry collection.
|
||||||
|
- Removing unrelated developer diagnostics.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Inventory debug overlay rendering callsites and tests.
|
||||||
|
2. Remove host overlay injection from Game and Shell render paths.
|
||||||
|
3. Delete overlay-specific drawing state, toggles, and fixture expectations.
|
||||||
|
4. Keep telemetry/logging APIs that do not render overlay pixels.
|
||||||
|
5. Update docs/specs to state that future debug UI requires a separate decision.
|
||||||
|
6. Run host and render tests.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- Host render path does not draw debug overlay pixels.
|
||||||
|
- Game and Shell output do not depend on host overlay state.
|
||||||
|
- Remaining diagnostics do not violate the render pipeline boundary.
|
||||||
|
- Docs do not preserve host overlay as an architectural requirement.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Run host render tests.
|
||||||
|
- Add or update tests proving overlay state does not affect final rendered output.
|
||||||
|
- Run `rg -n "debug overlay|overlay|DebugOverlay" crates specs discussion/workflow` and inspect remaining references.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- Removing overlay code can accidentally remove useful telemetry; keep non-render diagnostics intact.
|
||||||
|
- The word overlay may also refer to Game HUD/primitives; distinguish those from host debug overlay.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- Host desktop modules under `crates/`
|
||||||
|
- Host/render tests
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0085
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: PBS Stdlib and Syscall Declarations
|
||||||
|
status: open
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Update PBS Game and Shell stdlibs so high-level APIs map to app-mode-specific ABI domains: Game uses `composer.*` and `gfx2d.*`; Shell uses `gfxui.*`.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
PBS authors can keep ergonomic high-level APIs where appropriate, but generated or declared syscalls use the correct DEC-0030 ABI domain for the active app mode.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Update Game stdlib declarations for `composer.*` and `gfx2d.*`.
|
||||||
|
- Update Shell stdlib declarations for `gfxui.*`.
|
||||||
|
- Remove old primitive `gfx.*` ABI declarations.
|
||||||
|
- Keep author-facing wrappers clear about mode-specific behavior.
|
||||||
|
- Update examples/tests that compile PBS code.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Runtime implementation of the syscall handlers.
|
||||||
|
- New visual APIs beyond the domain split.
|
||||||
|
- Backward compatibility for old primitive `gfx.*` ABI declarations.
|
||||||
|
- Widget/layout redesign.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Inventory PBS stdlib files and syscall declaration generation.
|
||||||
|
2. Map Game scene/camera/sprites/HUD APIs to `composer.*`.
|
||||||
|
3. Map Game primitive APIs to `gfx2d.*`.
|
||||||
|
4. Map Shell primitive APIs to `gfxui.*`.
|
||||||
|
5. Remove or fail old primitive `gfx.*` ABI declarations.
|
||||||
|
6. Update PBS compile tests, examples, and syscall metadata expectations.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- PBS Game code emits only Game-allowed render ABI domains.
|
||||||
|
- PBS Shell code emits only Shell-allowed render ABI domains.
|
||||||
|
- Old primitive `gfx.*` ABI declarations are gone or explicitly rejected.
|
||||||
|
- Existing examples are updated to the new declarations.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Run PBS stdlib and compiler tests.
|
||||||
|
- Add Game and Shell declaration tests for emitted syscall names.
|
||||||
|
- Add negative tests for wrong-domain declarations.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- User-facing API names may remain similar while ABI names change; tests must assert emitted syscall domains, not just wrapper names.
|
||||||
|
- Examples can mask stale declarations if they do not compile in both Game and Shell contexts.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- PBS stdlib files
|
||||||
|
- Syscall declaration generation
|
||||||
|
- PBS tests and examples
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0086
|
||||||
|
ticket: render-frame-packet-boundary
|
||||||
|
title: End-to-End Render Boundary Validation
|
||||||
|
status: open
|
||||||
|
created: 2026-05-25
|
||||||
|
ref_decisions: [DEC-0030]
|
||||||
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Source decision: `DEC-0030`.
|
||||||
|
|
||||||
|
Add end-to-end validation proving the new boundary works across Game and Shell modes after the granular implementation plans land.
|
||||||
|
|
||||||
|
## Target
|
||||||
|
|
||||||
|
Integration coverage demonstrates typed submissions, app-mode capability gates, immutable closed submissions, render-surface publication, fade removal, and visible output preservation.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Add Game end-to-end tests from PBS/syscall production to `Game2DFramePacket` and final pixels.
|
||||||
|
- Add Shell end-to-end tests from UI production to `ShellUiFramePacket` and final pixels.
|
||||||
|
- Test wrong-domain capability failures.
|
||||||
|
- Test closed-submission immutability.
|
||||||
|
- Test latest-complete-submission-wins behavior.
|
||||||
|
- Test absence of fade and host debug overlay from canonical paths.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Implementing missing production code.
|
||||||
|
- New rendering features.
|
||||||
|
- Performance tuning.
|
||||||
|
- Dirty regions.
|
||||||
|
|
||||||
|
## Execution Sequence
|
||||||
|
|
||||||
|
1. Define representative Game and Shell scenarios that cover composer, `gfx2d`, and `gfxui`.
|
||||||
|
2. Add integration harness access to inspect closed submissions where appropriate.
|
||||||
|
3. Assert Game produces `RenderSubmission::Game2D` and Shell produces `RenderSubmission::ShellUi`.
|
||||||
|
4. Assert wrong-domain syscalls fail before mutating buffers.
|
||||||
|
5. Assert closed submissions remain unchanged after producers continue mutating the next frame.
|
||||||
|
6. Assert final pixels match existing expected output for unchanged scenarios.
|
||||||
|
7. Add searches or tests proving fade and host debug overlay are absent from the active render path.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- Game and Shell each have end-to-end typed submission tests.
|
||||||
|
- Capability gates reject `gfxui` in Game and `composer`/`gfx2d` in Shell.
|
||||||
|
- Closed submissions are immutable snapshots.
|
||||||
|
- Latest complete submission replaces older unpublished submissions without queue growth.
|
||||||
|
- Unchanged Game and Shell scenarios remain visually equivalent.
|
||||||
|
|
||||||
|
## Tests / Validation
|
||||||
|
|
||||||
|
- Run full affected Rust test suites.
|
||||||
|
- Run PBS compile/runtime integration tests.
|
||||||
|
- Run pixel-equivalence tests for representative Game and Shell output.
|
||||||
|
- Run `discussion validate` once execution discussion artifacts are updated.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- End-to-end tests may become brittle if they assert host details; assert the logical contract and final pixels, not internal host implementation names.
|
||||||
|
- Pixel-equivalence fixtures must account for intentional removals such as host debug overlay.
|
||||||
|
|
||||||
|
## Affected Artifacts
|
||||||
|
|
||||||
|
- Integration tests under `crates/`
|
||||||
|
- PBS tests
|
||||||
|
- Render fixtures
|
||||||
@ -9,7 +9,29 @@ Didactic companion: [`../learn/mental-model-gfx.md`](../runtime/learn/mental-mod
|
|||||||
|
|
||||||
The **GFX** peripheral is responsible for generating images in PROMETEU.
|
The **GFX** peripheral is responsible for generating images in PROMETEU.
|
||||||
|
|
||||||
It is an explicit 2D graphics device based on:
|
`DEC-0030` defines the current logical render boundary. PROMETEU render
|
||||||
|
production is split from render implementation:
|
||||||
|
|
||||||
|
```text
|
||||||
|
domain buffers during logical frame
|
||||||
|
-> RenderManager closes buffers
|
||||||
|
-> RenderSubmission snapshot
|
||||||
|
-> render surface / implementation consumes submission
|
||||||
|
-> RGBA8888 surface publication
|
||||||
|
```
|
||||||
|
|
||||||
|
The GFX peripheral remains the classic local raster implementation for
|
||||||
|
PROMETEU's 2D output. Logical render APIs do not target `Gfx` or the
|
||||||
|
framebuffer directly.
|
||||||
|
|
||||||
|
`RenderSubmission` is the closed snapshot passed across the render boundary. It
|
||||||
|
MUST contain a frame id, the active app mode, and one typed packet:
|
||||||
|
`Game2DFramePacket` for `AppMode::Game` or `ShellUiFramePacket` for
|
||||||
|
`AppMode::Shell`. Once closed, producers MUST treat the submission as
|
||||||
|
immutable. The runtime backpressure policy is latest-complete-submission-wins;
|
||||||
|
it MUST NOT accumulate an unbounded frame queue.
|
||||||
|
|
||||||
|
The current 2D graphics model is based on:
|
||||||
|
|
||||||
- framebuffer
|
- framebuffer
|
||||||
- tilemaps
|
- tilemaps
|
||||||
@ -48,19 +70,19 @@ palette, host presentation, or compatibility contract.
|
|||||||
|
|
||||||
## 3. Double Buffering
|
## 3. Double Buffering
|
||||||
|
|
||||||
The GFX maintains two buffers:
|
The render surface implementation maintains the concrete buffers needed to
|
||||||
|
publish a frame. The classic software implementation uses:
|
||||||
|
|
||||||
- **Back Buffer** — where the frame is built
|
- **Back Buffer** — where the frame is built
|
||||||
- **Front Buffer** — where the frame is displayed
|
- **Front Buffer** — where the frame is displayed
|
||||||
|
|
||||||
Per-frame flow:
|
Per-frame flow:
|
||||||
|
|
||||||
1. The system prepares the logical frame
|
1. Game or Shell code mutates mode-specific domain buffers during the logical frame.
|
||||||
2. Canonical game composition is rendered into the back buffer
|
2. `RenderManager` closes the active buffers into an immutable `RenderSubmission`.
|
||||||
3. Deferred final overlay/debug primitives are drained on top of the completed game frame
|
3. The render surface implementation consumes the submission and rasterizes to its back buffer.
|
||||||
4. Calls `present()`
|
4. The render surface publishes the completed RGBA8888 surface.
|
||||||
5. Buffers are swapped
|
5. The host displays the published surface.
|
||||||
6. The host displays the front buffer
|
|
||||||
|
|
||||||
This guarantees:
|
This guarantees:
|
||||||
|
|
||||||
@ -192,14 +214,20 @@ Access:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 10. Canonical Game Projection to the Back Buffer
|
## 10. Canonical Game Projection
|
||||||
|
|
||||||
For each frame:
|
Game mode uses a typed Game 2D submission. `composer.*` owns high-level Game 2D
|
||||||
|
frame composition: scene binding, camera, sprites, HUD, and frame orchestration.
|
||||||
|
`gfx2d.*` owns Game 2D primitives only. Both domains are mutable while the
|
||||||
|
logical frame is being produced and are closed by `RenderManager` into a
|
||||||
|
`Game2DFramePacket`.
|
||||||
|
|
||||||
|
For each Game 2D packet:
|
||||||
|
|
||||||
1. For each Tile Layer, in order:
|
1. For each Tile Layer, in order:
|
||||||
- Rasterize visible tiles from the cache
|
- Rasterize visible tiles from the cache
|
||||||
- Apply scroll, flip, and transparency
|
- Apply scroll, flip, and transparency
|
||||||
- Write to the back buffer
|
- Write to the render surface's working buffer
|
||||||
|
|
||||||
2. Draw sprites:
|
2. Draw sprites:
|
||||||
- With priority between layers
|
- With priority between layers
|
||||||
@ -207,9 +235,11 @@ For each frame:
|
|||||||
|
|
||||||
3. Draw HUD layer last
|
3. Draw HUD layer last
|
||||||
|
|
||||||
This section describes only the canonical game composition path.
|
4. Draw buffered `gfx2d.*` primitives according to the Game 2D packet contract.
|
||||||
|
|
||||||
`gfx.*` primitives such as `draw_text`, `draw_line`, and `draw_disc` are not part of this canonical game projection order. In v1 they belong to a deferred final overlay/debug stage that is drained after canonical game composition is complete.
|
This section describes only the Game 2D packet rendering path. Shell/system UI
|
||||||
|
uses `gfxui.*` and `ShellUiFramePacket`; it is never part of Game HUD or
|
||||||
|
`composer.*`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -227,15 +257,15 @@ Base order:
|
|||||||
4. Tile Layer 3
|
4. Tile Layer 3
|
||||||
5. Sprites (by priority between layers)
|
5. Sprites (by priority between layers)
|
||||||
6. HUD Layer
|
6. HUD Layer
|
||||||
7. Scene Fade
|
7. Buffered `gfx2d.*` Game primitives
|
||||||
8. HUD Fade
|
|
||||||
9. Deferred `gfx.*` overlay/debug primitives
|
|
||||||
|
|
||||||
Normative boundary:
|
Normative boundary:
|
||||||
|
|
||||||
- Items 1 through 8 belong to canonical game-frame composition.
|
- Items 1 through 6 belong to `composer.*` Game-frame composition.
|
||||||
- Item 9 is a separate overlay/debug stage.
|
- Item 7 belongs to `gfx2d.*`.
|
||||||
- Deferred `gfx.*` primitives MUST NOT be interpreted as scene, sprite, or canonical HUD content.
|
- `gfx2d.*` primitives MUST NOT be interpreted as scene, sprite, camera, HUD,
|
||||||
|
or frame orchestration.
|
||||||
|
- Shell/system UI belongs to `gfxui.*` and `ShellUiFramePacket`, not Game HUD.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -287,7 +317,8 @@ Everything is:
|
|||||||
|
|
||||||
- Blending occurs during drawing
|
- Blending occurs during drawing
|
||||||
- For canonical game composition, the result goes to the back buffer during composition
|
- For canonical game composition, the result goes to the back buffer during composition
|
||||||
- For deferred `gfx.*` overlay/debug primitives, the result is applied during the final overlay/debug drain stage
|
- For `gfx2d.*` and `gfxui.*` primitives, the result is applied when the render
|
||||||
|
surface consumes the closed packet for the active app mode
|
||||||
- There is no automatic GPU-style post-processing pipeline
|
- There is no automatic GPU-style post-processing pipeline
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -301,6 +332,7 @@ By design:
|
|||||||
- HDR
|
- HDR
|
||||||
- Gamma correction
|
- Gamma correction
|
||||||
- RGB565 compatibility framebuffers
|
- RGB565 compatibility framebuffers
|
||||||
|
- fade fields, fade syscalls, or fade packet members
|
||||||
- multi-format backend selection
|
- multi-format backend selection
|
||||||
- render-thread ownership as part of this contract
|
- render-thread ownership as part of this contract
|
||||||
|
|
||||||
@ -318,104 +350,24 @@ By design:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 17. Special PostFX — Fade (Scene and HUD)
|
## 17. Transitions and Removed Fade Contract
|
||||||
|
|
||||||
PROMETEU supports **gradual fade** as a special PostFX, with two independent
|
The previous special fade model is not part of the canonical render contract.
|
||||||
controls:
|
Current render packets, syscalls, and ABI domains MUST NOT expose scene fade,
|
||||||
|
HUD fade, fade levels, fade colors, or equivalent inherited fade state.
|
||||||
|
|
||||||
- **Scene Fade**: affects the entire scene (Tile Layers 0–3 + Sprites)
|
Future visual transitions between Shell and Game belong to `RenderManager`.
|
||||||
- **HUD Fade**: affects only the HUD Layer (always composed last)
|
They are not owned by `composer.*`, `gfx2d.*`, `gfxui.*`, `Game2DFramePacket`,
|
||||||
|
or `ShellUiFramePacket`.
|
||||||
In v1, deferred `gfx.*` overlay/debug primitives are drained after both fades and therefore are not themselves part of scene or HUD fade application.
|
|
||||||
|
|
||||||
The fade uses a **discrete integer level** (0..31), which in practice produces an
|
|
||||||
"almost continuous" visual result in Prometeu's `480x270` pixel-art framebuffer.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 17.1 Fade Representation
|
|
||||||
|
|
||||||
Each fade is represented by:
|
|
||||||
|
|
||||||
- `fade_level: u8` in the range **[0..31]**
|
|
||||||
- `0` → fully replaced by the fade color
|
|
||||||
- `31` → fully visible (no fade)
|
|
||||||
- `fade_color: RGBA8888`
|
|
||||||
- color the image will be blended into
|
|
||||||
|
|
||||||
Registers:
|
|
||||||
|
|
||||||
- `SCENE_FADE_LEVEL` (0..31)
|
|
||||||
- `SCENE_FADE_COLOR` (RGBA8888)
|
|
||||||
- `HUD_FADE_LEVEL` (0..31)
|
|
||||||
- `HUD_FADE_COLOR` (RGBA8888)
|
|
||||||
|
|
||||||
Common cases:
|
|
||||||
|
|
||||||
- Fade-out: `fade_color = BLACK`
|
|
||||||
- Flash/teleport: `fade_color = WHITE`
|
|
||||||
- Special effects: any RGBA8888 color
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 17.2 Fade Operation (Blending with Arbitrary Color)
|
|
||||||
|
|
||||||
For each RGBA8888 pixel `src` and fade color `fc`, the final pixel `dst` is calculated per channel.
|
|
||||||
|
|
||||||
1) Extract components:
|
|
||||||
|
|
||||||
- `src_r8`, `src_g8`, `src_b8`, `src_a8`
|
|
||||||
- `fc_r8`, `fc_g8`, `fc_b8`, `fc_a8`
|
|
||||||
|
|
||||||
2) Apply integer blending:
|
|
||||||
|
|
||||||
```
|
|
||||||
src_weight = fade_level // 0..31
|
|
||||||
fc_weight = 31 - fade_level
|
|
||||||
|
|
||||||
r8 = (src_r8 * src_weight + fc_r8 * fc_weight) / 31
|
|
||||||
g8 = (src_g8 * src_weight + fc_g8 * fc_weight) / 31
|
|
||||||
b8 = (src_b8 * src_weight + fc_b8 * fc_weight) / 31
|
|
||||||
a8 = (src_a8 * src_weight + fc_a8 * fc_weight) / 31
|
|
||||||
```
|
|
||||||
- `src_r8`, `src_g8`, `src_b8`, `src_a8`
|
|
||||||
- `fc_r8`, `fc_g8`, `fc_b8`, `fc_a8`
|
|
||||||
|
|
||||||
3) Repack:
|
|
||||||
|
|
||||||
```
|
|
||||||
dst = pack_rgba8888_rgba(r8, g8, b8, a8)
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
- Deterministic operation
|
|
||||||
- Integers only
|
|
||||||
- Can be optimized via LUT
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 17.3 Order of Application in the Frame
|
|
||||||
|
|
||||||
The frame composition follows this order:
|
|
||||||
|
|
||||||
1. Rasterize **Tile Layers 0–3** → Back Buffer
|
|
||||||
2. Rasterize **Sprites** according to priority
|
|
||||||
3. (Optional) Extra pipeline (Emission/Light/Glow etc.)
|
|
||||||
4. Apply **Scene Fade** using:
|
|
||||||
- `SCENE_FADE_LEVEL`
|
|
||||||
- `SCENE_FADE_COLOR`
|
|
||||||
5. Rasterize **HUD Layer**
|
|
||||||
6. Apply **HUD Fade** using:
|
|
||||||
- `HUD_FADE_LEVEL`
|
|
||||||
- `HUD_FADE_COLOR`
|
|
||||||
7. `present()`
|
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
|
|
||||||
- Scene Fade never affects the HUD
|
- render domain packets MUST NOT contain fade fields;
|
||||||
- HUD Fade never affects the scene
|
- public render syscalls MUST NOT expose fade controls;
|
||||||
|
- render implementations MUST NOT treat fade as an inherited post-processing
|
||||||
|
habit;
|
||||||
|
- transition work requires an explicit `RenderManager` contract or a later
|
||||||
|
decision.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -570,8 +522,13 @@ The system can measure:
|
|||||||
|
|
||||||
Graphics-related public ABI in v1 is split between:
|
Graphics-related public ABI in v1 is split between:
|
||||||
|
|
||||||
- `gfx.*` for direct drawing/backend-oriented operations;
|
- `composer.*` for Game 2D high-level frame composition;
|
||||||
- `composer.*` for frame orchestration operations.
|
- `gfx2d.*` for Game 2D primitives only;
|
||||||
|
- `gfxui.*` for Shell UI primitives only.
|
||||||
|
|
||||||
|
`composer.*` and `gfx2d.*` are available to `AppMode::Game`.
|
||||||
|
`gfxui.*` is available to `AppMode::Shell`. Renderers and capabilities may
|
||||||
|
differ by app mode.
|
||||||
|
|
||||||
Only operations with real operational rejection paths return explicit status values.
|
Only operations with real operational rejection paths return explicit status values.
|
||||||
|
|
||||||
@ -585,29 +542,32 @@ Fault boundary:
|
|||||||
|
|
||||||
| Syscall | Return | Policy basis |
|
| Syscall | Return | Policy basis |
|
||||||
| ----------------------- | ------------- | --------------------------------------------------- |
|
| ----------------------- | ------------- | --------------------------------------------------- |
|
||||||
| `gfx.clear` | `void` | no real operational failure path in v1 |
|
| `gfx2d.clear` | `void` | no real operational failure path in v1 |
|
||||||
| `gfx.fill_rect` | `void` | no real operational failure path in v1 |
|
| `gfx2d.fill_rect` | `void` | no real operational failure path in v1 |
|
||||||
| `gfx.draw_line` | `void` | no real operational failure path in v1 |
|
| `gfx2d.draw_line` | `void` | no real operational failure path in v1 |
|
||||||
| `gfx.draw_circle` | `void` | no real operational failure path in v1 |
|
| `gfx2d.draw_circle` | `void` | no real operational failure path in v1 |
|
||||||
| `gfx.draw_disc` | `void` | no real operational failure path in v1 |
|
| `gfx2d.draw_disc` | `void` | no real operational failure path in v1 |
|
||||||
| `gfx.draw_square` | `void` | no real operational failure path in v1 |
|
| `gfx2d.draw_square` | `void` | no real operational failure path in v1 |
|
||||||
| `gfx.draw_text` | `void` | no real operational failure path in v1 |
|
| `gfx2d.draw_text` | `void` | no real operational failure path in v1 |
|
||||||
|
| `gfxui.*` primitives | `void` | no real operational failure path in v1 |
|
||||||
| `composer.bind_scene` | `status:int` | status-returning API, but missing scene glyph dependencies are fatal runtime errors |
|
| `composer.bind_scene` | `status:int` | status-returning API, but missing scene glyph dependencies are fatal runtime errors |
|
||||||
| `composer.unbind_scene` | `status:int` | explicit orchestration-domain operational result |
|
| `composer.unbind_scene` | `status:int` | explicit orchestration-domain operational result |
|
||||||
| `composer.set_camera` | `void` | no real operational failure path in v1 |
|
| `composer.set_camera` | `void` | no real operational failure path in v1 |
|
||||||
| `composer.emit_sprite` | `status:int` | explicit orchestration-domain operational rejection |
|
| `composer.emit_sprite` | `status:int` | explicit orchestration-domain operational rejection |
|
||||||
|
|
||||||
### 19.1.a Deferred overlay/debug semantics for `gfx.*`
|
### 19.1.a Primitive domain semantics
|
||||||
|
|
||||||
The public `gfx.*` primitive family remains valid in v1, but its stable operational meaning is:
|
The primitive domains have stable operational meaning:
|
||||||
|
|
||||||
- deferred final overlay/debug composition;
|
- `gfx2d.*` is Game 2D primitive command buffering;
|
||||||
- screen-space and pipeline-agnostic relative to `composer.*`;
|
- `gfx2d.*` is screen-space and primitive-only relative to `composer.*`;
|
||||||
- outside `FrameComposer`;
|
- `gfx2d.*` is outside scene, camera, sprites, HUD, and Game 2D frame orchestration;
|
||||||
- above scene, sprites, and canonical HUD;
|
- `gfxui.*` is Shell UI primitive command buffering;
|
||||||
- drained after `hud_fade`.
|
- `gfxui.*` does not contain widget or layout policy.
|
||||||
|
|
||||||
This means callers MUST NOT rely on stable immediate writes to the working back buffer as the public contract for `gfx.draw_text(...)` or sibling primitives.
|
Callers MUST NOT rely on stable immediate writes to the working back buffer as
|
||||||
|
the public contract for primitive drawing. Primitive calls mutate domain command
|
||||||
|
buffers that close into the active typed submission.
|
||||||
|
|
||||||
### 19.1.b Scene dependency fatal boundary
|
### 19.1.b Scene dependency fatal boundary
|
||||||
|
|
||||||
|
|||||||
@ -116,26 +116,26 @@ Hardware differences:
|
|||||||
|
|
||||||
The graphics system:
|
The graphics system:
|
||||||
|
|
||||||
- operates on a logical RGBA8888 framebuffer
|
- produces typed logical render submissions that render to RGBA8888 output
|
||||||
- uses an indexed palette
|
- uses an indexed palette
|
||||||
- does not depend on a specific GPU
|
- does not depend on a specific GPU
|
||||||
|
|
||||||
The platform layer:
|
The platform layer:
|
||||||
|
|
||||||
- only displays the framebuffer
|
- consumes closed render submissions through a render-surface implementation
|
||||||
- does not reinterpret graphics commands
|
|
||||||
- **may overlay technical HUDs without modifying the logical framebuffer**
|
- **may overlay technical HUDs without modifying the logical framebuffer**
|
||||||
- may transport the logical framebuffer into a host presentation surface where a host-only overlay layer is composed
|
- may transport published RGBA8888 output into a host presentation surface where a host-only overlay layer is composed
|
||||||
|
|
||||||
The host presentation layer MUST treat RGBA8888 as the canonical logical
|
The host presentation layer MUST treat RGBA8888 as the canonical logical
|
||||||
framebuffer format. RGB565 conversion is not part of the normal host
|
framebuffer format. RGB565 conversion is not part of the normal host
|
||||||
presentation contract.
|
presentation contract.
|
||||||
|
|
||||||
Host presentation SHOULD be driven by published logical frames and explicit host-owned invalidation, not by perpetual redraw polling.
|
Host presentation SHOULD be driven by published render submissions and explicit
|
||||||
|
host-owned invalidation, not by perpetual redraw polling.
|
||||||
|
|
||||||
In particular:
|
In particular:
|
||||||
|
|
||||||
- a stable logical frame MAY remain visible across multiple host wakeups without recomposition;
|
- a stable published submission MAY remain visible across multiple host wakeups without recomposition;
|
||||||
- a host MAY redraw the same logical frame again when its own surface is invalidated by resize, expose, or host-only overlay/debug changes;
|
- a host MAY redraw the same logical frame again when its own surface is invalidated by resize, expose, or host-only overlay/debug changes;
|
||||||
- a host MUST NOT invent intermediate logical frames or require continuous redraw merely to discover whether a new logical frame exists.
|
- a host MUST NOT invent intermediate logical frames or require continuous redraw merely to discover whether a new logical frame exists.
|
||||||
|
|
||||||
|
|||||||
@ -220,29 +220,78 @@ For `asset.load`:
|
|||||||
- JSON-on-the-wire bank inspection payloads are not valid public ABI;
|
- JSON-on-the-wire bank inspection payloads are not valid public ABI;
|
||||||
- `bank.info` returns stack values, not textual structured payloads.
|
- `bank.info` returns stack values, not textual structured payloads.
|
||||||
|
|
||||||
### GFX surface (`gfx`, v1)
|
### Render surfaces (`composer`, `gfx2d`, `gfxui`, v1)
|
||||||
|
|
||||||
The public GFX ABI uses format-neutral operation names. API and syscall names
|
`DEC-0030` splits logical render production from render implementation. Public
|
||||||
MUST NOT encode RGB565 or any other pixel format suffix.
|
render syscalls mutate app-mode-specific domain buffers. They do not directly
|
||||||
|
publish a framebuffer and do not call host presentation APIs.
|
||||||
|
|
||||||
|
The canonical flow is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
domain buffers during logical frame
|
||||||
|
-> RenderManager closes buffers
|
||||||
|
-> RenderSubmission snapshot
|
||||||
|
-> render surface / implementation consumes submission
|
||||||
|
-> RGBA8888 surface publication
|
||||||
|
```
|
||||||
|
|
||||||
|
`RenderSubmission` is a typed closed snapshot containing `frame_id`, `app_mode`,
|
||||||
|
and exactly one packet: `Game2DFramePacket` for `AppMode::Game` or
|
||||||
|
`ShellUiFramePacket` for `AppMode::Shell`. Producers may mutate domain buffers
|
||||||
|
before closure only. Once `RenderManager` closes a submission, producers MUST
|
||||||
|
NOT mutate it. Backpressure is latest-complete-submission-wins; the runtime
|
||||||
|
MUST NOT expose an unbounded submission queue as part of the ABI.
|
||||||
|
|
||||||
|
Render API and syscall names MUST NOT encode RGB565 or any other pixel format
|
||||||
|
suffix.
|
||||||
|
|
||||||
|
#### Game 2D primitive surface (`gfx2d`, v1)
|
||||||
|
|
||||||
|
The `gfx2d` module is a Game profile primitive surface. It is limited to Game
|
||||||
|
2D primitive commands and does not own scene, camera, sprites, HUD, or frame
|
||||||
|
orchestration.
|
||||||
|
|
||||||
Canonical operations in v1 include:
|
Canonical operations in v1 include:
|
||||||
|
|
||||||
- `gfx.clear(color) -> void`
|
- `gfx2d.clear(color) -> void`
|
||||||
- `gfx.fill_rect(x, y, w, h, color) -> void`
|
- `gfx2d.fill_rect(x, y, w, h, color) -> void`
|
||||||
- `gfx.draw_line(x0, y0, x1, y1, color) -> void`
|
- `gfx2d.draw_line(x0, y0, x1, y1, color) -> void`
|
||||||
- `gfx.draw_circle(x, y, radius, color) -> void`
|
- `gfx2d.draw_circle(x, y, radius, color) -> void`
|
||||||
- `gfx.draw_disc(x, y, radius, color) -> void`
|
- `gfx2d.draw_disc(x, y, radius, color) -> void`
|
||||||
- `gfx.draw_square(x, y, size, color) -> void`
|
- `gfx2d.draw_square(x, y, size, color) -> void`
|
||||||
- `gfx.draw_text(x, y, text, color) -> void`
|
- `gfx2d.draw_text(x, y, text, color) -> void`
|
||||||
|
|
||||||
|
#### Shell UI primitive surface (`gfxui`, v1)
|
||||||
|
|
||||||
|
The `gfxui` module is a Shell profile primitive surface. It contains Shell UI
|
||||||
|
primitive commands only. Widget and layout policy belongs in Shell/UI code or
|
||||||
|
stdlib code, not in the host/render-surface implementation.
|
||||||
|
|
||||||
|
Canonical operations in v1 include primitive shapes equivalent to the subset
|
||||||
|
needed by Shell UI:
|
||||||
|
|
||||||
|
- `gfxui.clear(color) -> void`
|
||||||
|
- `gfxui.fill_rect(x, y, w, h, color) -> void`
|
||||||
|
- `gfxui.draw_line(x0, y0, x1, y1, color) -> void`
|
||||||
|
- `gfxui.draw_circle(x, y, radius, color) -> void`
|
||||||
|
- `gfxui.draw_disc(x, y, radius, color) -> void`
|
||||||
|
- `gfxui.draw_square(x, y, size, color) -> void`
|
||||||
|
- `gfxui.draw_text(x, y, text, color) -> void`
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
|
|
||||||
- `color` arguments are packed RGBA8888 values using RGBA channel order.
|
- `color` arguments are packed RGBA8888 values using RGBA channel order.
|
||||||
- RGB565 raw values are not a public ABI contract.
|
- RGB565 raw values are not a public ABI contract.
|
||||||
- `Gfx*565` syscall names and `gfx.*_565` canonical identities are not valid
|
- `Gfx*565` syscall names and `gfx*.*_565` canonical identities are not valid
|
||||||
current ABI.
|
current ABI.
|
||||||
- The runtime framebuffer exposed across the host boundary is RGBA8888, not
|
- The runtime framebuffer exposed across the host boundary is RGBA8888, not
|
||||||
`u16` RGB565.
|
`u16` RGB565.
|
||||||
|
- The old primitive `gfx.*` ABI is not the canonical render domain. PBS stdlibs
|
||||||
|
may expose ergonomic high-level names, but generated host bindings must map
|
||||||
|
to `gfx2d.*` in Game mode or `gfxui.*` in Shell mode.
|
||||||
|
- Render packets and public render syscalls MUST NOT expose fade fields or fade
|
||||||
|
controls.
|
||||||
|
|
||||||
### Composition surface (`composer`, v1)
|
### Composition surface (`composer`, v1)
|
||||||
|
|
||||||
@ -251,6 +300,11 @@ The canonical frame-orchestration public ABI uses module `composer`.
|
|||||||
The `composer` module is a game profile surface. It is not inherited by
|
The `composer` module is a game profile surface. It is not inherited by
|
||||||
`System` profile apps as their public UI/composition API.
|
`System` profile apps as their public UI/composition API.
|
||||||
|
|
||||||
|
`composer` owns Game 2D high-level frame composition: scene binding, camera,
|
||||||
|
sprites, HUD, and Game 2D frame orchestration. It closes into a
|
||||||
|
`Game2DFramePacket` through `RenderManager`; it does not publish or present a
|
||||||
|
framebuffer directly.
|
||||||
|
|
||||||
Canonical operations in v1 are:
|
Canonical operations in v1 are:
|
||||||
|
|
||||||
- `composer.bind_scene(bank_id) -> (status)`
|
- `composer.bind_scene(bank_id) -> (status)`
|
||||||
@ -264,6 +318,8 @@ For mutating composer operations:
|
|||||||
- `bind_scene`, `unbind_scene`, and `emit_sprite` are status-returning;
|
- `bind_scene`, `unbind_scene`, and `emit_sprite` are status-returning;
|
||||||
- `set_camera` remains `void` in v1;
|
- `set_camera` remains `void` in v1;
|
||||||
- no caller-provided sprite index or `active` flag is part of the canonical contract.
|
- no caller-provided sprite index or `active` flag is part of the canonical contract.
|
||||||
|
- no fade level, fade color, or transition control is part of the canonical
|
||||||
|
composer ABI.
|
||||||
|
|
||||||
Fatal boundary clarification for `bind_scene`:
|
Fatal boundary clarification for `bind_scene`:
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user