use crate::buffer::BufferDescriptor;
use crate::color::PixelFormat;
#[derive(Clone, Copy, Debug)]
pub struct BufferView<'a> {
data: &'a [u8],
desc: BufferDescriptor,
}
impl<'a> BufferView<'a> {
#[inline]
pub fn new(data: &'a [u8], desc: BufferDescriptor) -> Option<Self> {
if data.len() >= desc.size_bytes() {
Some(Self { data, desc })
} else {
None
}
}
#[inline]
pub unsafe fn new_unchecked(data: &'a [u8], desc: BufferDescriptor) -> Self {
Self { data, desc }
}
#[inline]
pub const fn descriptor(&self) -> &BufferDescriptor {
&self.desc
}
#[inline]
pub const fn width(&self) -> u32 {
self.desc.width
}
#[inline]
pub const fn height(&self) -> u32 {
self.desc.height
}
#[inline]
pub const fn stride(&self) -> u32 {
self.desc.stride
}
#[inline]
pub const fn format(&self) -> PixelFormat {
self.desc.format
}
#[inline]
pub fn data(&self) -> &[u8] {
self.data
}
#[inline]
pub fn row(&self, y: u32) -> Option<&[u8]> {
if y >= self.desc.height {
return None;
}
let start = self.desc.row_offset(y);
let end = start + self.desc.bytes_per_row() as usize;
Some(&self.data[start..end])
}
#[inline]
pub fn pixel_offset(&self, x: u32, y: u32) -> Option<usize> {
if x >= self.desc.width || y >= self.desc.height {
return None;
}
Some(self.desc.pixel_offset(x, y))
}
}
#[derive(Debug)]
pub struct BufferViewMut<'a> {
data: &'a mut [u8],
desc: BufferDescriptor,
}
impl<'a> BufferViewMut<'a> {
#[inline]
pub fn new(data: &'a mut [u8], desc: BufferDescriptor) -> Option<Self> {
if data.len() >= desc.size_bytes() {
Some(Self { data, desc })
} else {
None
}
}
#[inline]
pub unsafe fn new_unchecked(data: &'a mut [u8], desc: BufferDescriptor) -> Self {
Self { data, desc }
}
#[inline]
pub const fn descriptor(&self) -> &BufferDescriptor {
&self.desc
}
#[inline]
pub const fn width(&self) -> u32 {
self.desc.width
}
#[inline]
pub const fn height(&self) -> u32 {
self.desc.height
}
#[inline]
pub const fn stride(&self) -> u32 {
self.desc.stride
}
#[inline]
pub const fn format(&self) -> PixelFormat {
self.desc.format
}
#[inline]
pub fn data(&self) -> &[u8] {
self.data
}
#[inline]
pub fn data_mut(&mut self) -> &mut [u8] {
self.data
}
#[inline]
pub fn row_mut(&mut self, y: u32) -> Option<&mut [u8]> {
if y >= self.desc.height {
return None;
}
let start = self.desc.row_offset(y);
let end = start + self.desc.bytes_per_row() as usize;
Some(&mut self.data[start..end])
}
#[inline]
pub fn fill(&mut self, value: u8) {
self.data.fill(value);
}
#[inline]
pub fn clear(&mut self) {
self.fill(0);
}
}