implements PLN-0082 render publication boundary
This commit is contained in:
parent
74df4b89ac
commit
41266d3fd5
@ -11,7 +11,7 @@ use crate::touch::Touch;
|
|||||||
use prometeu_hal::cartridge::AssetsPayloadSource;
|
use prometeu_hal::cartridge::AssetsPayloadSource;
|
||||||
use prometeu_hal::sprite::Sprite;
|
use prometeu_hal::sprite::Sprite;
|
||||||
use prometeu_hal::{AssetBridge, AudioBridge, GfxBridge, HardwareBridge, PadBridge, TouchBridge};
|
use prometeu_hal::{AssetBridge, AudioBridge, GfxBridge, HardwareBridge, PadBridge, TouchBridge};
|
||||||
use prometeu_hal::{Game2DFramePacket, ShellUiFramePacket};
|
use prometeu_hal::{Game2DFramePacket, RenderSubmission, RenderSubmissionPacket};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Aggregate structure for all virtual hardware peripherals.
|
/// Aggregate structure for all virtual hardware peripherals.
|
||||||
@ -72,9 +72,21 @@ impl HardwareBridge for Hardware {
|
|||||||
self.frame_composer.close_game2d_packet()
|
self.frame_composer.close_game2d_packet()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_shell_ui_packet(&mut self, packet: &ShellUiFramePacket) {
|
fn publish_render_submission(&mut self, submission: &RenderSubmission) {
|
||||||
|
match &submission.packet {
|
||||||
|
RenderSubmissionPacket::Game2D(packet) => {
|
||||||
|
if self.frame_composer.active_scene_id().is_none() {
|
||||||
|
self.gfx.render_game2d_frame_packet(packet);
|
||||||
|
} else {
|
||||||
|
self.frame_composer.render_frame(&mut self.gfx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RenderSubmissionPacket::ShellUi(packet) => {
|
||||||
self.gfx.render_shell_ui_frame_packet(packet);
|
self.gfx.render_shell_ui_frame_packet(packet);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
self.gfx.present();
|
||||||
|
}
|
||||||
|
|
||||||
fn render_frame(&mut self) {
|
fn render_frame(&mut self) {
|
||||||
if self.frame_composer.active_scene_id().is_none() {
|
if self.frame_composer.active_scene_id().is_none() {
|
||||||
@ -85,10 +97,6 @@ impl HardwareBridge for Hardware {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn present(&mut self) {
|
|
||||||
self.gfx.present();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_glyph_bank(&self, bank_id: usize) -> bool {
|
fn has_glyph_bank(&self, bank_id: usize) -> bool {
|
||||||
self.gfx.glyph_banks.glyph_bank_slot(bank_id).is_some()
|
self.gfx.glyph_banks.glyph_bank_slot(bank_id).is_some()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -231,7 +231,7 @@ mod tests {
|
|||||||
debug_info: None,
|
debug_info: None,
|
||||||
exports: vec![],
|
exports: vec![],
|
||||||
syscalls: vec![SyscallDecl {
|
syscalls: vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
|
|||||||
@ -2,6 +2,7 @@ use crate::firmware::firmware_state::{FirmwareState, LaunchHubStep};
|
|||||||
use crate::firmware::prometeu_context::PrometeuContext;
|
use crate::firmware::prometeu_context::PrometeuContext;
|
||||||
use prometeu_hal::color::Color;
|
use prometeu_hal::color::Color;
|
||||||
use prometeu_hal::log::{LogLevel, LogSource};
|
use prometeu_hal::log::{LogLevel, LogSource};
|
||||||
|
use prometeu_hal::{FrameId, GfxUiCommand, RenderSubmission, ShellUiFramePacket};
|
||||||
use prometeu_system::CrashReport;
|
use prometeu_system::CrashReport;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -22,11 +23,8 @@ impl AppCrashesStep {
|
|||||||
// Update peripherals for input on the crash screen
|
// Update peripherals for input on the crash screen
|
||||||
ctx.hw.pad_mut().begin_frame(ctx.signals);
|
ctx.hw.pad_mut().begin_frame(ctx.signals);
|
||||||
|
|
||||||
// Error screen: red background, white text
|
let packet = ShellUiFramePacket::new(vec![GfxUiCommand::Clear { color: Color::RED }]);
|
||||||
ctx.hw.gfx_mut().clear(Color::RED);
|
ctx.hw.publish_render_submission(&RenderSubmission::shell_ui(FrameId::ZERO, packet));
|
||||||
// For now we just log or show something simple
|
|
||||||
// In the future, use draw_text
|
|
||||||
ctx.hw.gfx_mut().present();
|
|
||||||
|
|
||||||
// If START is pressed, return to the Hub
|
// If START is pressed, return to the Hub
|
||||||
if ctx.hw.pad().start().down {
|
if ctx.hw.pad().start().down {
|
||||||
|
|||||||
@ -38,10 +38,6 @@ impl GameRunningStep {
|
|||||||
|
|
||||||
let result = ctx.os.vm().tick(ctx.vm, ctx.signals, ctx.hw);
|
let result = ctx.os.vm().tick(ctx.vm, ctx.signals, ctx.hw);
|
||||||
|
|
||||||
if !ctx.os.vm().logical_frame_active() {
|
|
||||||
ctx.hw.gfx_mut().present();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(report) = result {
|
if let Some(report) = result {
|
||||||
let _ = ctx.os.lifecycle().crash_task(self.task_id, Some(&report));
|
let _ = ctx.os.lifecycle().crash_task(self.task_id, Some(&report));
|
||||||
return Some(FirmwareState::AppCrashes(AppCrashesStep { report }));
|
return Some(FirmwareState::AppCrashes(AppCrashesStep { report }));
|
||||||
|
|||||||
@ -2,6 +2,8 @@ use crate::firmware::firmware_state::{FirmwareState, LaunchHubStep};
|
|||||||
use crate::firmware::prometeu_context::PrometeuContext;
|
use crate::firmware::prometeu_context::PrometeuContext;
|
||||||
use prometeu_hal::color::Color;
|
use prometeu_hal::color::Color;
|
||||||
use prometeu_hal::log::{LogLevel, LogSource};
|
use prometeu_hal::log::{LogLevel, LogSource};
|
||||||
|
use prometeu_hal::primitives::Rect;
|
||||||
|
use prometeu_hal::{FrameId, GfxUiCommand, RenderSubmission, ShellUiFramePacket};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SplashScreenStep {
|
pub struct SplashScreenStep {
|
||||||
@ -22,9 +24,6 @@ impl SplashScreenStep {
|
|||||||
// Update peripherals for input
|
// Update peripherals for input
|
||||||
ctx.hw.pad_mut().begin_frame(ctx.signals);
|
ctx.hw.pad_mut().begin_frame(ctx.signals);
|
||||||
|
|
||||||
// Clear screen
|
|
||||||
ctx.hw.gfx_mut().clear(Color::ORANGE);
|
|
||||||
|
|
||||||
// Draw expanding square
|
// Draw expanding square
|
||||||
let (sw, sh) = ctx.hw.gfx().size();
|
let (sw, sh) = ctx.hw.gfx().size();
|
||||||
let max_size = (sw.min(sh) as i32 / 2).max(1);
|
let max_size = (sw.min(sh) as i32 / 2).max(1);
|
||||||
@ -38,8 +37,14 @@ impl SplashScreenStep {
|
|||||||
let x = (sw as i32 - current_size) / 2;
|
let x = (sw as i32 - current_size) / 2;
|
||||||
let y = (sh as i32 - current_size) / 2;
|
let y = (sh as i32 - current_size) / 2;
|
||||||
|
|
||||||
ctx.hw.gfx_mut().fill_rect(x, y, current_size, current_size, Color::WHITE);
|
let packet = ShellUiFramePacket::new(vec![
|
||||||
ctx.hw.gfx_mut().present();
|
GfxUiCommand::Clear { color: Color::ORANGE },
|
||||||
|
GfxUiCommand::FillRect {
|
||||||
|
rect: Rect { x, y, w: current_size, h: current_size },
|
||||||
|
color: Color::WHITE,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
ctx.hw.publish_render_submission(&RenderSubmission::shell_ui(FrameId::ZERO, packet));
|
||||||
|
|
||||||
// Transition logic
|
// Transition logic
|
||||||
// If any button is pressed at any time after the animation ends
|
// If any button is pressed at any time after the animation ends
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use crate::asset_bridge::AssetBridge;
|
|||||||
use crate::audio_bridge::AudioBridge;
|
use crate::audio_bridge::AudioBridge;
|
||||||
use crate::gfx_bridge::GfxBridge;
|
use crate::gfx_bridge::GfxBridge;
|
||||||
use crate::pad_bridge::PadBridge;
|
use crate::pad_bridge::PadBridge;
|
||||||
use crate::render_submission::{Game2DFramePacket, ShellUiFramePacket};
|
use crate::render_submission::{Game2DFramePacket, RenderSubmission};
|
||||||
use crate::sprite::Sprite;
|
use crate::sprite::Sprite;
|
||||||
use crate::touch_bridge::TouchBridge;
|
use crate::touch_bridge::TouchBridge;
|
||||||
|
|
||||||
@ -13,9 +13,8 @@ pub trait HardwareBridge {
|
|||||||
fn set_camera(&mut self, x: i32, y: i32);
|
fn set_camera(&mut self, x: i32, y: i32);
|
||||||
fn emit_sprite(&mut self, sprite: Sprite) -> bool;
|
fn emit_sprite(&mut self, sprite: Sprite) -> bool;
|
||||||
fn close_game2d_packet(&self) -> Game2DFramePacket;
|
fn close_game2d_packet(&self) -> Game2DFramePacket;
|
||||||
fn render_shell_ui_packet(&mut self, packet: &ShellUiFramePacket);
|
fn publish_render_submission(&mut self, submission: &RenderSubmission);
|
||||||
fn render_frame(&mut self);
|
fn render_frame(&mut self);
|
||||||
fn present(&mut self);
|
|
||||||
fn has_glyph_bank(&self, bank_id: usize) -> bool;
|
fn has_glyph_bank(&self, bank_id: usize) -> bool;
|
||||||
|
|
||||||
fn gfx(&self) -> &dyn GfxBridge;
|
fn gfx(&self) -> &dyn GfxBridge;
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
use crate::{CrashReport, SystemOS};
|
use crate::{CrashReport, SystemOS};
|
||||||
use prometeu_hal::color::Color;
|
use prometeu_hal::color::Color;
|
||||||
use prometeu_hal::primitives::Rect;
|
use prometeu_hal::primitives::Rect;
|
||||||
use prometeu_hal::{GfxUiCommand, HardwareBridge, InputSignals, ShellUiFramePacket};
|
use prometeu_hal::{
|
||||||
|
FrameId, GfxUiCommand, HardwareBridge, InputSignals, RenderSubmission, ShellUiFramePacket,
|
||||||
|
};
|
||||||
use prometeu_vm::VirtualMachine;
|
use prometeu_vm::VirtualMachine;
|
||||||
|
|
||||||
const SHELL_A_BUTTON: Rect = Rect { x: 112, y: 108, w: 112, h: 48 };
|
const SHELL_A_BUTTON: Rect = Rect { x: 112, y: 108, w: 112, h: 48 };
|
||||||
@ -140,7 +142,7 @@ impl PrometeuHub {
|
|||||||
}
|
}
|
||||||
ShellUiFramePacket::new(commands)
|
ShellUiFramePacket::new(commands)
|
||||||
};
|
};
|
||||||
hw.render_shell_ui_packet(&packet);
|
hw.publish_render_submission(&RenderSubmission::shell_ui(FrameId::ZERO, packet));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_shell_profile(
|
pub fn update_shell_profile(
|
||||||
@ -162,7 +164,6 @@ impl PrometeuHub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.render(os, hw);
|
self.render(os, hw);
|
||||||
hw.present();
|
|
||||||
|
|
||||||
SystemProfileUpdate { crash, action }
|
SystemProfileUpdate { crash, action }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -653,7 +653,6 @@ fn tick_renders_bound_eight_pixel_scene_through_frame_composer_path() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert!(report.is_none(), "frame render path must not crash");
|
assert!(report.is_none(), "frame render path must not crash");
|
||||||
hardware.gfx.present();
|
|
||||||
assert_eq!(hardware.gfx.front_buffer()[0], Color::BLUE.raw());
|
assert_eq!(hardware.gfx.front_buffer()[0], Color::BLUE.raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -729,7 +728,6 @@ fn tick_renders_scene_through_public_composer_syscalls() {
|
|||||||
|
|
||||||
assert!(report.is_none(), "public composer path must not crash");
|
assert!(report.is_none(), "public composer path must not crash");
|
||||||
assert_eq!(vm.operand_stack_top(1), vec![Value::Int64(ComposerOpStatus::Ok as i64)]);
|
assert_eq!(vm.operand_stack_top(1), vec![Value::Int64(ComposerOpStatus::Ok as i64)]);
|
||||||
hardware.gfx.present();
|
|
||||||
assert_eq!(hardware.gfx.front_buffer()[0], Color::BLUE.raw());
|
assert_eq!(hardware.gfx.front_buffer()[0], Color::BLUE.raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -785,7 +783,6 @@ fn tick_draw_text_survives_no_scene_frame_path() {
|
|||||||
};
|
};
|
||||||
assert_eq!(packet.gfx2d.len(), 1);
|
assert_eq!(packet.gfx2d.len(), 1);
|
||||||
assert!(matches!(packet.gfx2d[0], prometeu_hal::Gfx2dCommand::DrawText { .. }));
|
assert!(matches!(packet.gfx2d[0], prometeu_hal::Gfx2dCommand::DrawText { .. }));
|
||||||
hardware.gfx.present();
|
|
||||||
assert_eq!(hardware.gfx.front_buffer()[0], Color::from_raw(0x11223344).raw());
|
assert_eq!(hardware.gfx.front_buffer()[0], Color::from_raw(0x11223344).raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use super::dispatch::VmRuntimeHost;
|
use super::dispatch::VmRuntimeHost;
|
||||||
|
use super::render_manager::RenderSurface;
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::CrashReport;
|
use crate::CrashReport;
|
||||||
use crate::fs::{FsState, VirtualFS};
|
use crate::fs::{FsState, VirtualFS};
|
||||||
@ -6,13 +7,24 @@ use crate::services::memcard::MemcardService;
|
|||||||
use prometeu_hal::asset::{BankTelemetry, BankType};
|
use prometeu_hal::asset::{BankTelemetry, BankType};
|
||||||
use prometeu_hal::log::{LogLevel, LogService, LogSource};
|
use prometeu_hal::log::{LogLevel, LogService, LogSource};
|
||||||
use prometeu_hal::{
|
use prometeu_hal::{
|
||||||
HardwareBridge, HostContext, InputSignals, RenderSubmissionPacket, ShellUiFramePacket,
|
HardwareBridge, HostContext, InputSignals, RenderSubmission, RenderSubmissionPacket,
|
||||||
|
ShellUiFramePacket,
|
||||||
};
|
};
|
||||||
use prometeu_vm::LogicalFrameEndingReason;
|
use prometeu_vm::LogicalFrameEndingReason;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::panic::{AssertUnwindSafe, catch_unwind};
|
use std::panic::{AssertUnwindSafe, catch_unwind};
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
|
struct HardwareRenderSurface<'a> {
|
||||||
|
hw: &'a mut dyn HardwareBridge,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderSurface for HardwareRenderSurface<'_> {
|
||||||
|
fn consume_submission(&mut self, submission: &RenderSubmission) {
|
||||||
|
self.hw.publish_render_submission(submission);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl VirtualMachineRuntime {
|
impl VirtualMachineRuntime {
|
||||||
fn host_panic_payload_to_string(payload: Box<dyn std::any::Any + Send>) -> String {
|
fn host_panic_payload_to_string(payload: Box<dyn std::any::Any + Send>) -> String {
|
||||||
if let Some(message) = payload.downcast_ref::<String>() {
|
if let Some(message) = payload.downcast_ref::<String>() {
|
||||||
@ -237,7 +249,10 @@ impl VirtualMachineRuntime {
|
|||||||
.expect("shell packet must match Shell app mode");
|
.expect("shell packet must match Shell app mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(payload) = catch_unwind(AssertUnwindSafe(|| hw.render_frame())) {
|
if let Err(payload) = catch_unwind(AssertUnwindSafe(|| {
|
||||||
|
let mut surface = HardwareRenderSurface { hw };
|
||||||
|
self.render_manager.publish_latest(&mut surface);
|
||||||
|
})) {
|
||||||
let message = Self::host_panic_payload_to_string(payload);
|
let message = Self::host_panic_payload_to_string(payload);
|
||||||
let report = CrashReport::VmPanic { message, pc: Some(vm.pc() as u32) };
|
let report = CrashReport::VmPanic { message, pc: Some(vm.pc() as u32) };
|
||||||
self.log(
|
self.log(
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{"type":"meta","next_id":{"DSC":39,"AGD":39,"DEC":31,"PLN":87,"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":"done","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":"done","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":"done","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":"done","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":"done","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":"done","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":"done","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-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":"done","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":"done","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":"done","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":"done","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":"done","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":"done","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":"done","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":"done","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"}]}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
id: PLN-0082
|
id: PLN-0082
|
||||||
ticket: render-frame-packet-boundary
|
ticket: render-frame-packet-boundary
|
||||||
title: Frame Publication and Present Boundary
|
title: Frame Publication and Present Boundary
|
||||||
status: open
|
status: done
|
||||||
created: 2026-05-25
|
created: 2026-05-25
|
||||||
ref_decisions: [DEC-0030]
|
ref_decisions: [DEC-0030]
|
||||||
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user