use std::slice::{from_raw_parts, from_raw_parts_mut};
use crate::{ClippedRect, get_index};
use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
pub use rayon::max_num_threads;
pub fn blit_multi_threaded(
src: &[u8],
dst: &mut [u8],
rect: &ClippedRect,
stride: usize,
num_threads: usize,
) {
let src_ptr = src.as_ptr();
let dst_ptr = dst.as_mut_ptr();
let src_w = rect.src_size_clipped.w * stride;
let slices = (0..rect.src_size_clipped.h)
.map(|src_y| {
let src_index = get_index(0, src_y, rect.src_size.w, stride);
let dst_index = get_index(
rect.dst_position_clipped.x,
rect.dst_position_clipped.y + src_y,
rect.dst_size.w,
stride,
);
unsafe {
(
from_raw_parts(src_ptr.add(src_index), src_w),
from_raw_parts_mut(dst_ptr.add(dst_index), src_w),
)
}
})
.collect::<Vec<(&[u8], &mut [u8])>>();
let chunk_size = src.len() / num_threads;
slices
.into_par_iter()
.chunks(chunk_size)
.for_each(|slices| {
slices.into_iter().for_each(|(src, dst)| {
dst.copy_from_slice(src);
});
});
}