parent
d10d4cc65d
commit
257495aff7
@ -0,0 +1,69 @@
|
||||
use crate::ui::shape::DrawingCache;
|
||||
|
||||
use static_alloc::Bump;
|
||||
|
||||
/// Memory reserved for `ProgressiveRenderer`s shape storage.
|
||||
/// ProgressiveRenderer is used if framebuffer is not available.
|
||||
#[cfg(not(feature = "xframebuffer"))]
|
||||
pub const SHAPE_MEM_SIZE: usize = 5 * 1024;
|
||||
#[cfg(feature = "xframebuffer")]
|
||||
pub const SHAPE_MEM_SIZE: usize = 0;
|
||||
|
||||
/// Maximum number of shapes on a single screen
|
||||
/// (if you change it, you will probably need to change
|
||||
/// the memory size above)
|
||||
#[cfg(not(feature = "xframebuffer"))]
|
||||
pub const SHAPE_MAX_COUNT: usize = 45;
|
||||
#[cfg(feature = "xframebuffer")]
|
||||
pub const SHAPE_MAX_COUNT: usize = 0;
|
||||
|
||||
/// Size of `bump_a` memory that might not be accessible by DMA
|
||||
pub const BUMP_A_SIZE: usize = DrawingCache::get_bump_a_size() + SHAPE_MEM_SIZE;
|
||||
/// Size of `bump_b` memory that must be accessible by DMA
|
||||
pub const BUMP_B_SIZE: usize = DrawingCache::get_bump_b_size();
|
||||
|
||||
/// Runs a user-defined function with two bump allocators.
|
||||
///
|
||||
/// The function is passed two bump allocators, `bump_a` and `bump_b`, which
|
||||
/// can be used to allocate memory for temporary objects.
|
||||
///
|
||||
/// The function calls cannot be nested. The function panics if that happens.
|
||||
pub fn run_with_bumps<'a, F>(func: F)
|
||||
where
|
||||
F: FnOnce(&'a mut Bump<[u8; BUMP_A_SIZE]>, &'a mut Bump<[u8; BUMP_B_SIZE]>),
|
||||
{
|
||||
static mut LOCKED: bool = false;
|
||||
|
||||
// SAFETY:
|
||||
// The application is single-threaded, so we can safely use a
|
||||
// static variable as a lock against nested calls.
|
||||
|
||||
if unsafe { LOCKED } {
|
||||
panic!("nested run_with_bumps!");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
LOCKED = true;
|
||||
};
|
||||
|
||||
#[cfg_attr(not(target_os = "macos"), link_section = ".no_dma_buffers")]
|
||||
static mut BUMP_A: Bump<[u8; BUMP_A_SIZE]> = Bump::uninit();
|
||||
|
||||
#[cfg_attr(not(target_os = "macos"), link_section = ".buf")]
|
||||
static mut BUMP_B: Bump<[u8; BUMP_B_SIZE]> = Bump::uninit();
|
||||
|
||||
// SAFETY:
|
||||
// The function cannot be nested, so we can safely
|
||||
// use the static bump allocators.
|
||||
let bump_a = unsafe { &mut *core::ptr::addr_of_mut!(BUMP_A) };
|
||||
let bump_b = unsafe { &mut *core::ptr::addr_of_mut!(BUMP_B) };
|
||||
|
||||
bump_a.reset();
|
||||
bump_b.reset();
|
||||
|
||||
func(bump_a, bump_b);
|
||||
|
||||
unsafe {
|
||||
LOCKED = false;
|
||||
};
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
use crate::ui::{
|
||||
display::Color,
|
||||
shape::{Canvas, DirectRenderer, DrawingCache},
|
||||
};
|
||||
|
||||
use super::bumps::run_with_bumps;
|
||||
|
||||
/// Creates the `Renderer` object for drawing on a the specified and invokes a
|
||||
/// user-defined function that takes a single argument `target`. The user's
|
||||
/// function can utilize the `target` for drawing on the canvas.
|
||||
///
|
||||
/// `bg_color` specifies a background color with which the canvas is filled
|
||||
/// before the drawing starts. If the background color is None, the background
|
||||
/// is undefined, and the user has to fill it themselves.
|
||||
pub fn render_on_canvas<'a, C: Canvas, F>(canvas: &mut C, bg_color: Option<Color>, func: F)
|
||||
where
|
||||
F: FnOnce(&mut DirectRenderer<'_, 'a, C>),
|
||||
{
|
||||
run_with_bumps(|bump_a, bump_b| {
|
||||
let cache = DrawingCache::new(bump_a, bump_b);
|
||||
let mut target = DirectRenderer::new(canvas, bg_color, &cache);
|
||||
func(&mut target);
|
||||
});
|
||||
}
|
Loading…
Reference in new issue