parent
001acc770c
commit
89ae44ebfa
@ -0,0 +1,83 @@
|
||||
use crate::ui::{
|
||||
geometry::Offset,
|
||||
shape::{Bitmap, BitmapView, Canvas, CanvasBuilder},
|
||||
};
|
||||
|
||||
/// Size of image buffer in bytes
|
||||
const IMAGE_BUFFER_SIZE: usize = 64 * 1024;
|
||||
|
||||
#[repr(align(16))]
|
||||
struct AlignedBuffer {
|
||||
bytes: [u8; IMAGE_BUFFER_SIZE],
|
||||
}
|
||||
|
||||
/// Raw image buffer used by `ImageBuffer` instances.
|
||||
|
||||
static mut IMAGE_BUFFER: AlignedBuffer = AlignedBuffer {
|
||||
bytes: [0; IMAGE_BUFFER_SIZE],
|
||||
};
|
||||
|
||||
/// Set to `true` if the `IMAGE_BUFFER` is locked
|
||||
/// (in use by some instance of `ImageBuffer`)
|
||||
static mut IMAGE_BUFFER_LOCKED: bool = false;
|
||||
|
||||
/// A struct representing an image buffer - generic buffer for mutable images.
|
||||
pub struct ImageBuffer<T: Canvas + CanvasBuilder<'static>> {
|
||||
canvas: T,
|
||||
}
|
||||
|
||||
impl<T> Drop for ImageBuffer<T>
|
||||
where
|
||||
T: Canvas + CanvasBuilder<'static>,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
// It's safe to modify static variable as whole app
|
||||
// is single-threaded.
|
||||
unsafe {
|
||||
IMAGE_BUFFER_LOCKED = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ImageBuffer<T>
|
||||
where
|
||||
T: Canvas + CanvasBuilder<'static>,
|
||||
{
|
||||
/// Creates a new image buffer with the specified format and size.
|
||||
///
|
||||
/// Returns `None` if the buffer is already in use or the
|
||||
/// buffer is not big enough to hold the image.
|
||||
pub fn new(size: Offset) -> Option<Self> {
|
||||
// SAFETY:
|
||||
// It's safe to read/modify mutable static variable as
|
||||
// whole app is single-threaded.
|
||||
//
|
||||
// We can be sure that `IMAGE_BUFFER` is not shared between
|
||||
// multiple instances of `ImageBuffer` as we have `IMAGE_BUFFER_LOCKED`
|
||||
// to prevent that.
|
||||
unsafe {
|
||||
if IMAGE_BUFFER_LOCKED {
|
||||
return None;
|
||||
}
|
||||
|
||||
let bitmap =
|
||||
Bitmap::new_mut(T::format(), None, size, None, &mut IMAGE_BUFFER.bytes[..])?;
|
||||
|
||||
IMAGE_BUFFER_LOCKED = true;
|
||||
|
||||
Some(Self {
|
||||
canvas: T::from_bitmap(bitmap),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the canvas for the bitmap in the image buffer.
|
||||
pub fn canvas(&mut self) -> &mut T {
|
||||
&mut self.canvas
|
||||
}
|
||||
|
||||
/// Returns the immutable view of the bitmap in the image buffer.
|
||||
pub fn view(&self) -> BitmapView {
|
||||
self.canvas.view()
|
||||
}
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
mod blur;
|
||||
mod circle;
|
||||
mod imagebuf;
|
||||
mod line;
|
||||
mod trigo;
|
||||
|
||||
pub use blur::{BlurAlgorithm, BlurBuff};
|
||||
pub use circle::circle_points;
|
||||
pub use imagebuf::ImageBuffer;
|
||||
pub use line::line_points;
|
||||
pub use trigo::sin_f32;
|
||||
|
Loading…
Reference in new issue