implements PLN-0110
This commit is contained in:
parent
3916a652b2
commit
12d314a62d
@ -17,6 +17,7 @@ pub mod input_signals;
|
|||||||
pub mod log;
|
pub mod log;
|
||||||
pub mod native_helpers;
|
pub mod native_helpers;
|
||||||
pub mod native_interface;
|
pub mod native_interface;
|
||||||
|
pub mod owned_frame;
|
||||||
pub mod pad_bridge;
|
pub mod pad_bridge;
|
||||||
pub mod platform;
|
pub mod platform;
|
||||||
pub mod primitives;
|
pub mod primitives;
|
||||||
@ -44,6 +45,7 @@ pub use host_return::HostReturn;
|
|||||||
pub use input_signals::InputSignals;
|
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 owned_frame::{OwnedRgba8888Frame, OwnedRgba8888FrameError};
|
||||||
pub use pad_bridge::PadBridge;
|
pub use pad_bridge::PadBridge;
|
||||||
pub use platform::{
|
pub use platform::{
|
||||||
AssetStoragePlatform, AudioPlatform, ClockPacingPlatform, Game2DFrameComposer, InputPlatform,
|
AssetStoragePlatform, AudioPlatform, ClockPacingPlatform, Game2DFrameComposer, InputPlatform,
|
||||||
|
|||||||
127
crates/console/prometeu-hal/src/owned_frame.rs
Normal file
127
crates/console/prometeu-hal/src/owned_frame.rs
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
use crate::render_submission::{FrameId, RenderOwnership};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct OwnedRgba8888Frame {
|
||||||
|
pub frame_id: FrameId,
|
||||||
|
pub ownership: RenderOwnership,
|
||||||
|
pub width: usize,
|
||||||
|
pub height: usize,
|
||||||
|
pub stride_pixels: usize,
|
||||||
|
pub pixels: Vec<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum OwnedRgba8888FrameError {
|
||||||
|
EmptyDimensions,
|
||||||
|
StrideTooSmall,
|
||||||
|
PixelBufferTooSmall,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OwnedRgba8888Frame {
|
||||||
|
pub fn new(
|
||||||
|
frame_id: FrameId,
|
||||||
|
ownership: RenderOwnership,
|
||||||
|
width: usize,
|
||||||
|
height: usize,
|
||||||
|
stride_pixels: usize,
|
||||||
|
pixels: Vec<u32>,
|
||||||
|
) -> Result<Self, OwnedRgba8888FrameError> {
|
||||||
|
if width == 0 || height == 0 {
|
||||||
|
return Err(OwnedRgba8888FrameError::EmptyDimensions);
|
||||||
|
}
|
||||||
|
if stride_pixels < width {
|
||||||
|
return Err(OwnedRgba8888FrameError::StrideTooSmall);
|
||||||
|
}
|
||||||
|
let required_len = stride_pixels
|
||||||
|
.checked_mul(height)
|
||||||
|
.ok_or(OwnedRgba8888FrameError::PixelBufferTooSmall)?;
|
||||||
|
if pixels.len() < required_len {
|
||||||
|
return Err(OwnedRgba8888FrameError::PixelBufferTooSmall);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self { frame_id, ownership, width, height, stride_pixels, pixels })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn packed(
|
||||||
|
frame_id: FrameId,
|
||||||
|
ownership: RenderOwnership,
|
||||||
|
width: usize,
|
||||||
|
height: usize,
|
||||||
|
pixels: Vec<u32>,
|
||||||
|
) -> Result<Self, OwnedRgba8888FrameError> {
|
||||||
|
Self::new(frame_id, ownership, width, height, width, pixels)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn required_pixel_len(&self) -> usize {
|
||||||
|
self.stride_pixels * self.height
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn row(&self, y: usize) -> Option<&[u32]> {
|
||||||
|
if y >= self.height {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let start = y * self.stride_pixels;
|
||||||
|
Some(&self.pixels[start..start + self.width])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::app_mode::AppMode;
|
||||||
|
|
||||||
|
fn ownership() -> RenderOwnership {
|
||||||
|
RenderOwnership::new(11, AppMode::Game, 42)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn owned_rgba8888_frame_preserves_metadata_and_pixels() {
|
||||||
|
let pixels = vec![0x11223344, 0x55667788, 0x99AABBCC, 0xDDEEFF00];
|
||||||
|
let frame = OwnedRgba8888Frame::packed(FrameId::new(7), ownership(), 2, 2, pixels.clone())
|
||||||
|
.expect("valid packed RGBA8888 frame");
|
||||||
|
|
||||||
|
assert_eq!(frame.frame_id, FrameId::new(7));
|
||||||
|
assert_eq!(frame.ownership, ownership());
|
||||||
|
assert_eq!(frame.width, 2);
|
||||||
|
assert_eq!(frame.height, 2);
|
||||||
|
assert_eq!(frame.stride_pixels, 2);
|
||||||
|
assert_eq!(frame.pixels, pixels);
|
||||||
|
assert_eq!(frame.required_pixel_len(), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn checked_constructor_rejects_empty_dimensions() {
|
||||||
|
let err = OwnedRgba8888Frame::new(FrameId::ZERO, ownership(), 0, 1, 1, vec![0])
|
||||||
|
.expect_err("zero width should be rejected");
|
||||||
|
|
||||||
|
assert_eq!(err, OwnedRgba8888FrameError::EmptyDimensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn checked_constructor_rejects_stride_smaller_than_width() {
|
||||||
|
let err = OwnedRgba8888Frame::new(FrameId::ZERO, ownership(), 3, 1, 2, vec![0, 0, 0])
|
||||||
|
.expect_err("stride smaller than width should be rejected");
|
||||||
|
|
||||||
|
assert_eq!(err, OwnedRgba8888FrameError::StrideTooSmall);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn checked_constructor_rejects_short_pixel_buffer() {
|
||||||
|
let err = OwnedRgba8888Frame::new(FrameId::ZERO, ownership(), 2, 2, 3, vec![0; 5])
|
||||||
|
.expect_err("buffer shorter than stride * height should be rejected");
|
||||||
|
|
||||||
|
assert_eq!(err, OwnedRgba8888FrameError::PixelBufferTooSmall);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn row_returns_visible_width_without_stride_padding() {
|
||||||
|
let frame =
|
||||||
|
OwnedRgba8888Frame::new(FrameId::ZERO, ownership(), 2, 2, 3, vec![1, 2, 99, 3, 4, 88])
|
||||||
|
.expect("valid padded frame");
|
||||||
|
|
||||||
|
assert_eq!(frame.row(0), Some(&[1, 2][..]));
|
||||||
|
assert_eq!(frame.row(1), Some(&[3, 4][..]));
|
||||||
|
assert_eq!(frame.row(2), None);
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@ -2,7 +2,7 @@
|
|||||||
id: PLN-0110
|
id: PLN-0110
|
||||||
ticket: real-render-worker-establishment
|
ticket: real-render-worker-establishment
|
||||||
title: Define Owned RGBA8888 Frame Contract
|
title: Define Owned RGBA8888 Frame Contract
|
||||||
status: open
|
status: done
|
||||||
created: 2026-06-15
|
created: 2026-06-15
|
||||||
completed:
|
completed:
|
||||||
ref_decisions: [DEC-0033]
|
ref_decisions: [DEC-0033]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user