Skip to content

Commit 0908f61

Browse files
committed
Add graphics readback and clear.
1 parent 76cc849 commit 0908f61

3 files changed

Lines changed: 72 additions & 0 deletions

File tree

crates/processing_ffi/src/lib.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,23 @@ pub extern "C" fn processing_background_image(graphics_id: u64, image_id: u64) {
226226
});
227227
}
228228

229+
/// Clear the graphics surface to transparent.
230+
///
231+
/// SAFETY:
232+
/// - graphics_id is a valid ID returned from graphics_create.
233+
/// - This is called from the same thread as init.
234+
#[unsafe(no_mangle)]
235+
pub extern "C" fn processing_clear(graphics_id: u64) {
236+
error::clear_error();
237+
let graphics_entity = Entity::from_bits(graphics_id);
238+
error::check(|| {
239+
graphics_record_command(
240+
graphics_entity,
241+
DrawCommand::BackgroundColor(bevy::prelude::Color::NONE),
242+
)
243+
});
244+
}
245+
229246
/// Begins the draw for the given graphics context.
230247
///
231248
/// SAFETY:
@@ -1601,6 +1618,47 @@ pub unsafe extern "C" fn processing_image_readback(
16011618
});
16021619
}
16031620

1621+
/// Load pixels from the graphics surface into a caller-provided buffer.
1622+
///
1623+
/// # Safety
1624+
/// - Init and graphics_create have been called.
1625+
/// - graphics_id is a valid ID returned from graphics_create.
1626+
/// - buffer is a valid pointer to at least buffer_len Color elements.
1627+
/// - buffer_len must equal width * height of the graphics surface.
1628+
/// - This is called from the same thread as init.
1629+
#[unsafe(no_mangle)]
1630+
pub unsafe extern "C" fn processing_graphics_readback(
1631+
graphics_id: u64,
1632+
buffer: *mut Color,
1633+
buffer_len: usize,
1634+
) {
1635+
error::clear_error();
1636+
let graphics_entity = Entity::from_bits(graphics_id);
1637+
error::check(|| {
1638+
let colors = graphics_readback(graphics_entity)?;
1639+
1640+
if colors.len() != buffer_len {
1641+
let error_msg = format!(
1642+
"Buffer size mismatch: expected {}, got {}",
1643+
colors.len(),
1644+
buffer_len
1645+
);
1646+
error::set_error(&error_msg);
1647+
return Err(error::ProcessingError::InvalidArgument(error_msg));
1648+
}
1649+
1650+
// SAFETY: Caller guarantees buffer is valid for buffer_len elements
1651+
unsafe {
1652+
let buffer_slice = std::slice::from_raw_parts_mut(buffer, buffer_len);
1653+
for (i, color) in colors.iter().enumerate() {
1654+
buffer_slice[i] = Color::from_linear(*color);
1655+
}
1656+
}
1657+
1658+
Ok(())
1659+
});
1660+
}
1661+
16041662
/// Set the tint color applied to images.
16051663
///
16061664
/// SAFETY:

crates/processing_pyo3/src/graphics.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,14 @@ impl Graphics {
664664
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
665665
}
666666

667+
pub fn clear(&self) -> PyResult<()> {
668+
graphics_record_command(
669+
self.entity,
670+
DrawCommand::BackgroundColor(bevy::prelude::Color::NONE),
671+
)
672+
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
673+
}
674+
667675
#[pyo3(signature = (*args))]
668676
pub fn fill(&self, args: &Bound<'_, PyTuple>) -> PyResult<()> {
669677
if args.len() == 1

crates/processing_pyo3/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,12 @@ mod mewnala {
11331133
}
11341134
}
11351135

1136+
#[pyfunction]
1137+
#[pyo3(pass_module)]
1138+
fn clear(module: &Bound<'_, PyModule>) -> PyResult<()> {
1139+
graphics!(module).clear()
1140+
}
1141+
11361142
#[pyfunction]
11371143
#[pyo3(pass_module, signature = (mode, max1=None, max2=None, max3=None, max_alpha=None))]
11381144
fn color_mode<'py>(

0 commit comments

Comments
 (0)