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 blur;
|
||||||
mod circle;
|
mod circle;
|
||||||
|
mod imagebuf;
|
||||||
mod line;
|
mod line;
|
||||||
mod trigo;
|
mod trigo;
|
||||||
|
|
||||||
pub use blur::{BlurAlgorithm, BlurBuff};
|
pub use blur::{BlurAlgorithm, BlurBuff};
|
||||||
pub use circle::circle_points;
|
pub use circle::circle_points;
|
||||||
|
pub use imagebuf::ImageBuffer;
|
||||||
pub use line::line_points;
|
pub use line::line_points;
|
||||||
pub use trigo::sin_f32;
|
pub use trigo::sin_f32;
|
||||||
|
Loading…
Reference in new issue