mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/utils/image/overlay.rs')
-rw-r--r--src/utils/image/overlay.rs69
1 files changed, 35 insertions, 34 deletions
diff --git a/src/utils/image/overlay.rs b/src/utils/image/overlay.rs
index 9cad52e..4406a9b 100644
--- a/src/utils/image/overlay.rs
+++ b/src/utils/image/overlay.rs
@@ -1,4 +1,4 @@
-use super::{really_unsafe_index, unsafe_assert, Image};
+use super::{assert_unchecked, really_unsafe_index, Image};
use std::simd::SimdInt;
use std::simd::SimdPartialOrd;
use std::simd::{simd_swizzle, Simd};
@@ -28,8 +28,8 @@ pub unsafe fn blit(rgb: &mut [u8], rgba: &[u8]) {
let mut srci = 0;
let mut dsti = 0;
while dsti + 16 <= rgb.len() {
- let old: Simd<u8, 16> = Simd::from_slice(rgb.get_unchecked(dsti..dsti + 16));
- let new: Simd<u8, 16> = Simd::from_slice(rgba.get_unchecked(srci..srci + 16));
+ let old: Simd<u8, 16> = Simd::from_slice(unsafe { rgb.get_unchecked(dsti..dsti + 16) });
+ let new: Simd<u8, 16> = Simd::from_slice(unsafe { rgba.get_unchecked(srci..srci + 16) });
let threshold = new.simd_ge(Simd::splat(128)).to_int().cast::<u8>();
let mut mask = simd_swizzle!(
@@ -40,19 +40,17 @@ pub unsafe fn blit(rgb: &mut [u8], rgba: &[u8]) {
let new_rgb = simd_swizzle!(new, [0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 0, 0, 0, 0]);
let blended = (new_rgb & mask) | (old & !mask);
- blended.copy_to_slice(rgb.get_unchecked_mut(dsti..dsti + 16));
+ blended.copy_to_slice(unsafe { rgb.get_unchecked_mut(dsti..dsti + 16) });
srci += 16;
dsti += 12;
}
while dsti + 3 <= rgb.len() {
- if *rgba.get_unchecked(srci + 3) >= 128 {
- std::ptr::copy_nonoverlapping(
- rgba.get_unchecked(srci..srci + 3).as_ptr(),
- rgb.get_unchecked_mut(dsti..dsti + 3).as_mut_ptr(),
- 3,
- );
+ if unsafe { *rgba.get_unchecked(srci + 3) } >= 128 {
+ let src = unsafe { rgba.get_unchecked(srci..srci + 3) };
+ let end = unsafe { rgb.get_unchecked_mut(dsti..dsti + 3) };
+ unsafe { std::ptr::copy_nonoverlapping(src.as_ptr(), end.as_mut_ptr(), 3) };
}
srci += 4;
@@ -62,8 +60,9 @@ pub unsafe fn blit(rgb: &mut [u8], rgba: &[u8]) {
impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 3> {
unsafe fn overlay_at(&mut self, with: &Image<&[u8], 4>, x: u32, y: u32) -> &mut Self {
- unsafe_assert!(x + with.width() <= self.width());
- unsafe_assert!(y + with.height() <= self.height());
+ // SAFETY: caller upholds these
+ unsafe { assert_unchecked!(x + with.width() <= self.width()) };
+ unsafe { assert_unchecked!(y + with.height() <= self.height()) };
for j in 0..with.height() {
let i_x = j as usize * with.width() as usize * 4
..(j as usize + 1) * with.width() as usize * 4;
@@ -72,10 +71,9 @@ impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 3> {
+ x as usize
+ with.width() as usize)
* 3;
- blit(
- self.buffer.get_unchecked_mut(o_x),
- with.buffer.get_unchecked(i_x),
- )
+ let rgb = unsafe { self.buffer.get_unchecked_mut(o_x) };
+ let rgba = unsafe { with.buffer.get_unchecked(i_x) };
+ unsafe { blit(rgb, rgba) }
}
self
}
@@ -83,19 +81,19 @@ impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 3> {
impl Overlay<Image<&[u8], 4>> for Image<&mut [u8], 3> {
unsafe fn overlay(&mut self, with: &Image<&[u8], 4>) -> &mut Self {
- unsafe_assert!(self.width() == with.width());
- unsafe_assert!(self.height() == with.height());
+ unsafe { assert_unchecked!(self.width() == with.width()) };
+ unsafe { assert_unchecked!(self.height() == with.height()) };
for (i, chunk) in with
.buffer
.chunks_exact(with.width() as usize * 4)
.enumerate()
{
- blit(
+ let rgb = unsafe {
self.buffer.get_unchecked_mut(
i * with.width() as usize * 3..(i + 1) * with.width() as usize * 3,
- ),
- chunk,
- );
+ )
+ };
+ unsafe { blit(rgb, chunk) };
}
self
}
@@ -105,18 +103,21 @@ impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 4> {
unsafe fn overlay_at(&mut self, with: &Image<&[u8], 4>, x: u32, y: u32) -> &mut Self {
for j in 0..with.height() {
for i in 0..with.width() {
- let with_index = really_unsafe_index(i, j, with.width()).unchecked_mul(4);
- let their_px = with
- .buffer
- .get_unchecked(with_index..with_index.unchecked_add(4));
- if *their_px.get_unchecked(3) >= 128 {
- let our_index =
- really_unsafe_index(i.unchecked_add(x), j.unchecked_add(y), self.width())
- .unchecked_mul(4);
- let our_px = self
- .buffer
- .get_unchecked_mut(our_index..our_index.unchecked_add(4));
- std::ptr::copy_nonoverlapping(their_px.as_ptr(), our_px.as_mut_ptr(), 4);
+ // TODO: see how many unchecked maths i can get rid of
+ let index_begin = unsafe { really_unsafe_index(i, j, with.width()) };
+ let index_begin = unsafe { index_begin.unchecked_mul(4) };
+ let index_end = unsafe { index_begin.unchecked_add(4) };
+ let their_px = unsafe { with.buffer.get_unchecked(index_begin..index_end) };
+ if unsafe { *their_px.get_unchecked(3) } >= 128 {
+ let x = unsafe { i.unchecked_add(x) };
+ let y = unsafe { j.unchecked_add(y) };
+ let index_begin = unsafe { really_unsafe_index(x, y, self.width()) };
+ let index_begin = unsafe { index_begin.unchecked_mul(4) };
+ let index_end = unsafe { index_begin.unchecked_add(4) };
+ let our_px = unsafe { self.buffer.get_unchecked_mut(index_begin..index_end) };
+ unsafe {
+ std::ptr::copy_nonoverlapping(their_px.as_ptr(), our_px.as_mut_ptr(), 4)
+ };
}
}
}