mindustry logic execution, map- and schematic- parsing and rendering
add a bench for hot overlays
| -rw-r--r-- | src/data/renderer.rs | 4 | ||||
| -rw-r--r-- | src/lib.rs | 3 | ||||
| -rw-r--r-- | src/utils/image/mod.rs | 17 | ||||
| -rw-r--r-- | src/utils/image/overlay.rs | 61 |
4 files changed, 65 insertions, 20 deletions
diff --git a/src/data/renderer.rs b/src/data/renderer.rs index 4ceef76..d9e1ddc 100644 --- a/src/data/renderer.rs +++ b/src/data/renderer.rs @@ -39,14 +39,14 @@ impl std::ops::Mul<u32> for Scale { #[macro_export] macro_rules! load { ("empty", $scale:expr) => { - ImageHolder::from(match $scale { + $crate::utils::image::ImageHolder::from(match $scale { $crate::data::renderer::Scale::Quarter => &$crate::data::renderer::quar::EMPTY, $crate::data::renderer::Scale::Eigth => &$crate::data::renderer::eigh::EMPTY, $crate::data::renderer::Scale::Full => &$crate::data::renderer::full::EMPTY, }.copy()) }; ($name:literal, $scale:expr) => { paste::paste! { - ImageHolder::from(match $scale { + $crate::utils::image::ImageHolder::from(match $scale { $crate::data::renderer::Scale::Quarter => &$crate::data::renderer::quar::[<$name:snake:upper>], $crate::data::renderer::Scale::Eigth => &$crate::data::renderer::eigh::[<$name:snake:upper>], $crate::data::renderer::Scale::Full => &$crate::data::renderer::full::[<$name:snake:upper>], @@ -7,7 +7,8 @@ slice_swap_unchecked, portable_simd, let_chains, - effects + effects, + test )] #![warn( clippy::missing_safety_doc, diff --git a/src/utils/image/mod.rs b/src/utils/image/mod.rs index bb89e09..bbe9a3e 100644 --- a/src/utils/image/mod.rs +++ b/src/utils/image/mod.rs @@ -6,22 +6,7 @@ use affine::*; mod holder; mod overlay; pub use holder::*; - -pub trait OverlayAt<W> { - /// Overlay with => self at coordinates x, y, without blending - /// # Safety - /// - /// UB if x, y is out of bounds - unsafe fn overlay_at(&mut self, with: &W, x: u32, y: u32) -> &mut Self; -} - -pub trait Overlay<W> { - /// Overlay with => self (does not blend) - /// # Safety - /// - /// UB if a.width != b.width || a.height != b.height - unsafe fn overlay(&mut self, with: &W) -> &mut Self; -} +pub use overlay::*; pub trait RepeatNew { type Output; diff --git a/src/utils/image/overlay.rs b/src/utils/image/overlay.rs index aee251c..9cad52e 100644 --- a/src/utils/image/overlay.rs +++ b/src/utils/image/overlay.rs @@ -1,8 +1,24 @@ -use super::{really_unsafe_index, unsafe_assert, Image, Overlay, OverlayAt}; +use super::{really_unsafe_index, unsafe_assert, Image}; use std::simd::SimdInt; use std::simd::SimdPartialOrd; use std::simd::{simd_swizzle, Simd}; +pub trait OverlayAt<W> { + /// Overlay with => self at coordinates x, y, without blending + /// # Safety + /// + /// UB if x, y is out of bounds + unsafe fn overlay_at(&mut self, with: &W, x: u32, y: u32) -> &mut Self; +} + +pub trait Overlay<W> { + /// Overlay with => self (does not blend) + /// # Safety + /// + /// UB if a.width != b.width || a.height != b.height + unsafe fn overlay(&mut self, with: &W) -> &mut Self; +} + #[inline] pub unsafe fn blit(rgb: &mut [u8], rgba: &[u8]) { const LAST4: Simd<u8, 16> = Simd::from_array([ @@ -108,3 +124,46 @@ impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 4> { self } } + +#[cfg(test)] +mod bench { + extern crate test; + use test::{black_box, Bencher}; + + use super::*; + use crate::{data::renderer::Scale, load}; + + #[bench] + fn overlay_4on3at(bench: &mut Bencher) { + let mut v = vec![0u8; 3 * 56 * 56]; + let mut a: Image<_, 3> = Image::new( + 56.try_into().unwrap(), + 56.try_into().unwrap(), + v.as_mut_slice(), + ); + let b = load!("interplanetary-accelerator", Scale::Eigth); + bench.iter(|| unsafe { + black_box(a.overlay_at(&b.borrow(), 0, 0)); + black_box(a.overlay_at(&b.borrow(), 28, 0)); + black_box(a.overlay_at(&b.borrow(), 28, 28)); + black_box(a.overlay_at(&b.borrow(), 0, 28)); + }); + } + + #[bench] + fn overlay_4on4at(bench: &mut Bencher) { + let mut v = vec![0u8; 4 * 56 * 56]; + let mut a: Image<_, 4> = Image::new( + 56.try_into().unwrap(), + 56.try_into().unwrap(), + v.as_mut_slice(), + ); + let b = load!("interplanetary-accelerator", Scale::Eigth); + bench.iter(|| unsafe { + black_box(a.overlay_at(&b.borrow(), 0, 0)); + black_box(a.overlay_at(&b.borrow(), 28, 0)); + black_box(a.overlay_at(&b.borrow(), 28, 28)); + black_box(a.overlay_at(&b.borrow(), 0, 28)); + }); + } +} |