167 lines
7.8 KiB
Markdown
167 lines
7.8 KiB
Markdown
---
|
|
id: DEC-0015
|
|
ticket: frame-composer-public-syscall-surface
|
|
title: FrameComposer Public Syscall Surface
|
|
status: accepted
|
|
created: 2026-04-17
|
|
accepted: 2026-04-17
|
|
agenda: AGD-0027
|
|
plans: [PLN-0022, PLN-0023, PLN-0024, PLN-0025]
|
|
tags: [gfx, runtime, syscall, abi, frame-composer, scene, camera, sprites]
|
|
---
|
|
|
|
## Status
|
|
|
|
Accepted.
|
|
|
|
## Contexto
|
|
|
|
`DEC-0014` locked `FrameComposer` as the canonical internal frame orchestration service and `PLN-0017` through `PLN-0021` completed that internal migration path. `Hardware` now owns `FrameComposer`, the runtime renders through `FrameComposer.render_frame()`, and scene/camera/cache/resolver/sprite ownership no longer belongs canonically to `Gfx`.
|
|
|
|
That migration did not define the equivalent public syscall contract for VM code. The public ABI still exposed legacy `gfx`-domain sprite control while the canonical scene/camera operations existed only as internal driver APIs.
|
|
|
|
This decision closes that public ABI gap without reopening the already accepted internal ownership model.
|
|
|
|
## Decisao
|
|
|
|
The canonical public syscall surface for frame orchestration SHALL move to the `composer.*` namespace.
|
|
|
|
Normatively:
|
|
|
|
- The canonical public service domain for `FrameComposer` operations SHALL be `composer`.
|
|
- The initial canonical syscall set SHALL be:
|
|
- `composer.bind_scene(bank_id) -> ComposerOpStatus`
|
|
- `composer.unbind_scene() -> ComposerOpStatus`
|
|
- `composer.set_camera(x, y)`
|
|
- `composer.emit_sprite(glyph_id, palette_id, x, y, layer, bank_id, flip_x, flip_y, priority) -> ComposerOpStatus`
|
|
- `composer.emit_sprite(...)` SHALL be the canonical public sprite submission path.
|
|
- `composer.emit_sprite(...)` MUST NOT require a caller-provided sprite index.
|
|
- `composer.emit_sprite(...)` MUST carry `layer` and `priority`.
|
|
- `composer.emit_sprite(...)` MUST NOT expose `active` as part of the canonical contract.
|
|
- `composer.bind_scene(...)`, `composer.unbind_scene()`, and `composer.emit_sprite(...)` SHALL return `ComposerOpStatus`.
|
|
- `composer.set_camera(x, y)` SHALL keep the minimal V1 camera contract already accepted by `DEC-0014`:
|
|
- `x` and `y` are `i32` pixel coordinates;
|
|
- they represent the top-left viewport origin in world space.
|
|
- The public ABI MUST NOT expose cache refresh policy or explicit refresh controls.
|
|
- The public ABI MUST NOT expose scene/camera introspection in this first phase.
|
|
- `gfx.set_sprite(...)` MUST be removed completely from the public contract.
|
|
- No compatibility shim for `gfx.set_sprite(...)` SHALL remain as part of the canonical migration target.
|
|
- Introduction of `composer.*` and removal of `gfx.set_sprite(...)` SHALL be executed in the same migration thread.
|
|
|
|
## Rationale
|
|
|
|
The public ABI must reflect the accepted ownership model rather than preserve a misleading legacy shape.
|
|
|
|
Keeping the canonical public surface under `gfx.*` would continue to tie orchestration semantics to the wrong service boundary. The new namespace makes the ownership change explicit:
|
|
|
|
- `Gfx` is the visual backend;
|
|
- `FrameComposer` is the frame orchestration service.
|
|
|
|
Removing `gfx.set_sprite(...)` completely avoids prolonging a dual public sprite model. A compatibility shim would preserve legacy slot/index semantics in the public contract after those semantics had already ceased to be canonical internally.
|
|
|
|
Returning `ComposerOpStatus` for operational mutating calls preserves status-first behavior while keeping the public contract aligned with the new service boundary. Reusing `GfxOpStatus` would leak backend-domain semantics into orchestration-domain syscalls after that separation had already been made explicit.
|
|
|
|
Deferring introspection and explicit refresh controls keeps the first public ABI focused on control, not diagnostics or internal policy leakage.
|
|
|
|
## Invariantes / Contrato
|
|
|
|
### 1. Namespace
|
|
|
|
- Public frame-orchestration syscalls MUST live under `composer.*`.
|
|
- `composer.*` SHALL be treated as the canonical public orchestration surface.
|
|
- `gfx.*` SHALL NOT remain the canonical public orchestration namespace for scene/camera/sprite submission.
|
|
|
|
### 2. Scene Control
|
|
|
|
- `composer.bind_scene(bank_id)` MUST bind by scene bank id.
|
|
- Binding semantics MUST remain aligned with `DEC-0014`:
|
|
- scene resolution through the scene bank pool;
|
|
- explicit bind/unbind lifecycle;
|
|
- no implicit per-frame rebinding.
|
|
- `composer.unbind_scene()` MUST leave no-scene rendering valid.
|
|
- `ComposerOpStatus` SHALL be the canonical operational status family for composer-domain mutating syscalls.
|
|
|
|
### 3. Camera
|
|
|
|
- `composer.set_camera(x, y)` MUST remain the minimal V1 camera API.
|
|
- Camera follow, smoothing, shake, transitions, and readback are OUT OF SCOPE for this decision.
|
|
|
|
### 4. Sprite Submission
|
|
|
|
- `composer.emit_sprite(...)` MUST be frame-emission based.
|
|
- The caller MUST NOT provide sprite slot/index information.
|
|
- The public payload MUST include:
|
|
- `glyph_id`
|
|
- `palette_id`
|
|
- `x`
|
|
- `y`
|
|
- `layer`
|
|
- `bank_id`
|
|
- `flip_x`
|
|
- `flip_y`
|
|
- `priority`
|
|
- The canonical public sprite contract MUST NOT include `active`.
|
|
- Overflow behavior SHALL remain aligned with `DEC-0014`:
|
|
- excess sprites are ignored;
|
|
- overflow is not a hard VM fault in V1.
|
|
|
|
### 5. Non-Goals for V1 Public ABI
|
|
|
|
- No public refresh/invalidate syscalls.
|
|
- No public cache inspection syscalls.
|
|
- No public `scene_status()` syscall.
|
|
- No public `get_camera()` syscall.
|
|
|
|
### 6. Migration Contract
|
|
|
|
- Migration MUST update:
|
|
- syscall registry and ABI resolution;
|
|
- runtime dispatch;
|
|
- bytecode/cartridge declarations;
|
|
- tests;
|
|
- stress cartridges and related tooling where applicable.
|
|
- Migration MUST NOT leave `gfx.set_sprite(...)` as a supported public fallback after the new contract lands.
|
|
|
|
## Impactos
|
|
|
|
### HAL
|
|
|
|
- The syscall enum, registry, metadata, and resolver will need a new `composer` domain surface.
|
|
- `gfx.set_sprite(...)` must be removed from the public ABI contract.
|
|
- A new `ComposerOpStatus` contract will need to be introduced for composer-domain operational returns.
|
|
|
|
### Runtime / VM
|
|
|
|
- Runtime dispatch must route public scene/camera/sprite orchestration through `FrameComposer`.
|
|
- Existing bytecode declarations and cartridges that rely on `gfx.set_sprite(...)` will need coordinated migration.
|
|
|
|
### Spec / ABI / ISA_CORE
|
|
|
|
- The canonical spec for the public VM-facing graphics/composition surface must be updated to reflect `composer.*`.
|
|
- ABI-facing documentation and contracts must be updated wherever syscall domain, names, arguments, or return semantics are specified.
|
|
- `ISA_CORE` must be updated if and where it normatively references the public syscall surface affected by this decision.
|
|
|
|
### Drivers / Hardware
|
|
|
|
- `FrameComposer` already has the required internal base; execution work will focus on public ABI exposure rather than internal ownership redesign.
|
|
|
|
### Tooling / Stress
|
|
|
|
- Stress cartridges and bytecode generators can only exercise the canonical frame path publicly after `composer.*` exists.
|
|
|
|
## Referencias
|
|
|
|
- [AGD-0027-frame-composer-public-syscall-surface.md](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/discussion/workflow/agendas/AGD-0027-frame-composer-public-syscall-surface.md)
|
|
- [DEC-0014-frame-composer-render-integration.md](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/discussion/workflow/decisions/DEC-0014-frame-composer-render-integration.md)
|
|
|
|
## Propagacao Necessaria
|
|
|
|
- A new implementation plan MUST be created from this decision before code changes.
|
|
- The plan MUST cover ABI introduction, legacy syscall removal, cartridge/test migration, regression coverage, and canonical spec propagation.
|
|
- The plan MUST explicitly assess and update ABI and `ISA_CORE` artifacts where this decision changes documented public behavior.
|
|
- Stress tooling SHOULD be updated as part of the migration thread so the public ABI can exercise the canonical frame path end-to-end.
|
|
|
|
## Revision Log
|
|
|
|
- 2026-04-17: Initial accepted decision from `AGD-0027`.
|